Skip to content

Conversation

nielash
Copy link
Collaborator

@nielash nielash commented Sep 4, 2025

What is the purpose of this change?

Two fixes for bisync integration tests on koofr and chunker.

@ncw For the chunker issue (which I think I tracked down), it should be noted that there is an underlying bug in operations that this PR does not fix, but just side-steps.

The bug is that operations.Move (per its function comment) is supposed to be only accounted as a check. But on backends like S3 which can Copy but not Move, the move falls back to server-side copy and ends up getting counted as a transfer anyway, even when isTransfer == false.

// 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)
}

newDst, err = Copy(ctx, fdst, dst, origRemote, src)

tr := accounting.Stats(ctx).NewTransfer(src, f)

This could theoretically be fixed by making a similar Copy / CopyTransfer scheme and/or passing an isTransfer param to Copy. But as Copy has lots of callers, that's a potentially invasive change that I deemed out-of-scope for this PR 😅

See the 68a9019 commit message for further explanation about why this affects chunker differently from other backends.

Was the change discussed in an issue or in the forum before?

Checklist

  • I have read the contribution guidelines.
  • I have added tests for all changes in this PR if appropriate.
  • I have added documentation for the changes if appropriate.
  • All commit messages are in house style.
  • I'm done, this Pull Request is ready for review :-)

Before this change, koofr failed certain bisync tests because it can't set mod
time without deleting and re-uploading. This caused the "nothing to transfer" log
to not get printed where expected (as it is only printed when there are 0
transfers, but koofr requires extra transfers to set modtime.)

This change fixes the issue by ignoring the absence of the "nothing to transfer"
log line on backends that return `fs.ErrorCantSetModTimeWithoutDelete` for
`obj.SetModTime`.
Before this change, TestChunkerS3: tests were failing because our use of
obj.Remove (for "modtime_write_test") created an unexpected extra transfer.

This is because chunker calls operations.Move for removes, which (per its
function comment) is supposed to be only accounted as a check. But because S3
can Copy but not Move, the move falls back to copy and ends up getting counted
as a transfer anyway.
https://github.com/rclone/rclone/blob/99e8a63df2528e4fd470821095cbeb32e8a827a3/fs/operations/operations.go#L506
https://github.com/rclone/rclone/blob/99e8a63df2528e4fd470821095cbeb32e8a827a3/fs/operations/copy.go#L381

This is probably a bug that should get a more proper fix in operations. But in
the meantime, we can get around it by doing our "modtime_write_test" with its
own unique stats group.
Copy link
Member

@ncw ncw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look great - thank you :-)

Please merge

@nielash nielash merged commit d915f75 into rclone:master Sep 4, 2025
9 checks passed
@github-project-automation github-project-automation bot moved this from In progress to Done in bisync Sep 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants