vfs: make WriteAt for non cached files work with non-sequential writes

This makes WriteAt for non cached files wait a short time if it gets
an out of order write (which would normally cause an error) to see if
the gap will be filled with an in order write.

The makes the SFTP backend work fine with --vfs-cache-mode off
This commit is contained in:
Nick Craig-Wood 2019-05-10 13:22:55 +01:00
parent ada8c22a97
commit af030f74f5

View File

@ -121,11 +121,20 @@ func (fh *WriteFileHandle) WriteAt(p []byte, off int64) (n int, err error) {
// Implementatino of WriteAt - call with lock held // Implementatino of WriteAt - call with lock held
func (fh *WriteFileHandle) writeAt(p []byte, off int64) (n int, err error) { func (fh *WriteFileHandle) writeAt(p []byte, off int64) (n int, err error) {
// fs.Debugf(fh.remote, "WriteFileHandle.Write len=%d", len(p)) // defer log.Trace(fh.remote, "len=%d off=%d", len(p), off)("n=%d, fh.off=%d, err=%v", &n, &fh.offset, &err)
if fh.closed { if fh.closed {
fs.Errorf(fh.remote, "WriteFileHandle.Write: error: %v", EBADF) fs.Errorf(fh.remote, "WriteFileHandle.Write: error: %v", EBADF)
return 0, ECLOSED return 0, ECLOSED
} }
// Wait a short time for sequential writes to appear
const maxTries = 1000
const sleepTime = 1 * time.Millisecond
for try := 1; fh.offset != off && try <= maxTries; try++ {
//fs.Debugf(fh.remote, "waiting for in sequence write %d/%d", try, maxTries)
fh.mu.Unlock()
time.Sleep(sleepTime)
fh.mu.Lock()
}
if fh.offset != off { if fh.offset != off {
fs.Errorf(fh.remote, "WriteFileHandle.Write: can't seek in file without --vfs-cache-mode >= writes") fs.Errorf(fh.remote, "WriteFileHandle.Write: can't seek in file without --vfs-cache-mode >= writes")
return 0, ESPIPE return 0, ESPIPE