From bfbddab46be5d971e5486223c528943ba9aa84f8 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 12 Sep 2019 11:12:19 +0100 Subject: [PATCH] fs/accounting: Fix "file already closed" on transfer retries This was caused by the recent reworking of the accounting interface. The Transfer object was recycling the Accounting object without resetting the stream. See: https://forum.rclone.org/t/error-file-already-closed/11469/ See: https://forum.rclone.org/t/rclone-b2-sync-post-error-method-not-supported/11718/ --- fs/accounting/accounting.go | 8 ++++++-- fs/accounting/transfer.go | 2 ++ fs/operations/operations.go | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/accounting/accounting.go b/fs/accounting/accounting.go index 5d1229b29..50282ff26 100644 --- a/fs/accounting/accounting.go +++ b/fs/accounting/accounting.go @@ -118,11 +118,15 @@ func (acc *Account) StopBuffering() { // async buffer (if any) and re-adding it func (acc *Account) UpdateReader(in io.ReadCloser) { acc.mu.Lock() - acc.StopBuffering() + if acc.withBuf { + acc.StopBuffering() + } acc.in = in acc.close = in acc.origIn = in - acc.WithBuffer() + if acc.withBuf { + acc.WithBuffer() + } acc.mu.Unlock() } diff --git a/fs/accounting/transfer.go b/fs/accounting/transfer.go index 0d968661b..a1ab8d023 100644 --- a/fs/accounting/transfer.go +++ b/fs/accounting/transfer.go @@ -117,6 +117,8 @@ func (tr *Transfer) Account(in io.ReadCloser) *Account { tr.mu.Lock() if tr.acc == nil { tr.acc = newAccountSizeName(tr.stats, in, tr.size, tr.remote) + } else { + tr.acc.UpdateReader(in) } tr.mu.Unlock() return tr.acc diff --git a/fs/operations/operations.go b/fs/operations/operations.go index 8e5a9e707..dbc626dfc 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -346,6 +346,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj } else { actionTaken = "Copied (Rcat, new)" } + // NB Rcat closes in0 dst, err = Rcat(ctx, f, remote, in0, src.ModTime(ctx)) newDst = dst } else {