From fbdf71ab64567c4715640ef761254a44fed2d9a9 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 4 Jan 2024 11:28:47 +0000 Subject: [PATCH] operations: fix files moved by rclone move not being counted as transfers Before this change we were only counting moves as checks. This means that when using `rclone move` the `Transfers` stat did not count up like it should do. This changes introduces a new primitive operations.MoveTransfers which counts moves as Transfers for use where that is appropriate, such as rclone move/moveto. Otherwise moves are counted as checks and their bytes are not accounted. See: #7183 See: https://forum.rclone.org/t/stats-one-line-date-broken-in-1-64-0-and-later/43263/ --- fs/operations/operations.go | 26 ++++++++++++++++++++++++-- fs/sync/sync.go | 2 +- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/fs/operations/operations.go b/fs/operations/operations.go index a7e2f6d50..62d03ab37 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -332,9 +332,29 @@ func SameObject(src, dst fs.Object) bool { // // It returns the destination object if possible. Note that this may // be nil. +// +// This is accounted as a check. func Move(ctx context.Context, fdst fs.Fs, dst fs.Object, remote string, src fs.Object) (newDst fs.Object, err error) { + return move(ctx, fdst, dst, remote, src, false) +} + +// MoveTransfer moves src object to dst or fdst if nil. If dst is nil +// then it uses remote as the name of the new object. +// +// This is identical to Move but is accounted as a transfer. +func MoveTransfer(ctx context.Context, fdst fs.Fs, dst fs.Object, remote string, src fs.Object) (newDst fs.Object, err error) { + return move(ctx, fdst, dst, remote, src, true) +} + +// move - see Move for help +func move(ctx context.Context, fdst fs.Fs, dst fs.Object, remote string, src fs.Object, isTransfer bool) (newDst fs.Object, err error) { ci := fs.GetConfig(ctx) - tr := accounting.Stats(ctx).NewCheckingTransfer(src, "moving") + var tr *accounting.Transfer + if isTransfer { + tr = accounting.Stats(ctx).NewTransfer(src) + } else { + tr = accounting.Stats(ctx).NewCheckingTransfer(src, "moving") + } defer func() { if err == nil { accounting.Stats(ctx).Renames(1) @@ -1695,7 +1715,7 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str } // Choose operations - Op := Move + Op := MoveTransfer if cp { Op = Copy } @@ -1797,6 +1817,8 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str } // MoveFile moves a single file possibly to a new name +// +// This is treated as a transfer. func MoveFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName string, srcFileName string) (err error) { return moveOrCopyFile(ctx, fdst, fsrc, dstFileName, srcFileName, false) } diff --git a/fs/sync/sync.go b/fs/sync/sync.go index 255dfaf1a..18a8b67b7 100644 --- a/fs/sync/sync.go +++ b/fs/sync/sync.go @@ -437,7 +437,7 @@ func (s *syncCopyMove) pairCopyOrMove(ctx context.Context, in *pipe, fdst fs.Fs, dst := pair.Dst if s.DoMove { if src != dst { - _, err = operations.Move(ctx, fdst, dst, src.Remote(), src) + _, err = operations.MoveTransfer(ctx, fdst, dst, src.Remote(), src) } else { // src == dst signals delete the src err = operations.DeleteFile(ctx, src)