From 50a4ed8fc44184788bf06fda588efe88aa9410f8 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 28 Aug 2019 17:35:58 +0100 Subject: [PATCH] operations: fix accounting for server side copies See: https://forum.rclone.org/t/b2-server-side-copy-doesnt-show-cumulative-progress/11154 --- fs/accounting/accounting.go | 22 ++++++++++++++++++++++ fs/operations/operations.go | 7 ++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/fs/accounting/accounting.go b/fs/accounting/accounting.go index 81a1b56f5..5d1229b29 100644 --- a/fs/accounting/accounting.go +++ b/fs/accounting/accounting.go @@ -168,6 +168,28 @@ func (acc *Account) checkRead() (err error) { return nil } +// ServerSideCopyStart should be called at the start of a server side copy +// +// This pretends a transfer has started +func (acc *Account) ServerSideCopyStart() { + acc.statmu.Lock() + // Set start time. + if acc.start.IsZero() { + acc.start = time.Now() + } + acc.statmu.Unlock() +} + +// ServerSideCopyEnd accounts for a read of n bytes in a sever side copy +func (acc *Account) ServerSideCopyEnd(n int64) { + // Update Stats + acc.statmu.Lock() + acc.bytes += n + acc.statmu.Unlock() + + acc.stats.Bytes(n) +} + // Account the read and limit bandwidth func (acc *Account) accountRead(n int) { // Update Stats diff --git a/fs/operations/operations.go b/fs/operations/operations.go index c7c4934e6..e0b7c5ca0 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -302,10 +302,15 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj if fs.Config.MaxTransfer >= 0 && accounting.Stats(ctx).GetBytes() >= int64(fs.Config.MaxTransfer) { return nil, accounting.ErrorMaxTransferLimitReached } + in := tr.Account(nil) // account the transfer + in.ServerSideCopyStart() newDst, err = doCopy(ctx, src, remote) if err == nil { dst = newDst - accounting.Stats(ctx).Bytes(dst.Size()) // account the bytes for the server side transfer + in.ServerSideCopyEnd(dst.Size()) // account the bytes for the server side transfer + err = in.Close() + } else { + _ = in.Close() } } else { err = fs.ErrorCantCopy