mount: fix hang on errored upload

In certain circumstances if an upload failed then the mount could hang
indefinitely. This was fixed by closing the read pipe after the Put
completed.  This will cause the write side to return a pipe closed
error fixing the hang.

Fixes #1498
This commit is contained in:
Nick Craig-Wood 2017-06-26 11:58:12 +01:00
parent 52b042971a
commit b360527931

View file

@ -13,7 +13,6 @@ type WriteFileHandle struct {
mu sync.Mutex mu sync.Mutex
closed bool // set if handle has been closed closed bool // set if handle has been closed
remote string remote string
pipeReader *io.PipeReader
pipeWriter *io.PipeWriter pipeWriter *io.PipeWriter
o fs.Object o fs.Object
result chan error result chan error
@ -39,10 +38,16 @@ func newWriteFileHandle(d *Dir, f *File, src fs.ObjectInfo) (*WriteFileHandle, e
file: f, file: f,
hash: hash, hash: hash,
} }
fh.pipeReader, fh.pipeWriter = io.Pipe() var pipeReader *io.PipeReader
r := fs.NewAccountSizeName(fh.pipeReader, 0, src.Remote()).WithBuffer() // account the transfer pipeReader, fh.pipeWriter = io.Pipe()
go func() { go func() {
r := fs.NewAccountSizeName(pipeReader, 0, src.Remote()).WithBuffer() // account the transfer
o, err := d.f.Put(r, src) o, err := d.f.Put(r, src)
if err != nil {
fs.Errorf(fh.remote, "WriteFileHandle.New Put failed: %v", err)
}
// Close the Account and thus the pipeReader so the pipeWriter fails with ErrClosedPipe
_ = r.Close()
fh.o = o fh.o = o
fh.result <- err fh.result <- err
}() }()
@ -120,14 +125,10 @@ func (fh *WriteFileHandle) close() error {
fh.file.addWriters(-1) fh.file.addWriters(-1)
writeCloseErr := fh.pipeWriter.Close() writeCloseErr := fh.pipeWriter.Close()
err := <-fh.result err := <-fh.result
readCloseErr := fh.pipeReader.Close()
if err == nil { if err == nil {
fh.file.setObject(fh.o) fh.file.setObject(fh.o)
err = writeCloseErr err = writeCloseErr
} }
if err == nil {
err = readCloseErr
}
if err == nil && fh.hash != nil { if err == nil && fh.hash != nil {
for hashType, srcSum := range fh.hash.Sums() { for hashType, srcSum := range fh.hash.Sums() {
dstSum, err := fh.o.Hash(hashType) dstSum, err := fh.o.Hash(hashType)