Skip to content

fix: stop forcing size-only sync comparisons via RCLONE_LOCAL_NO_SET_MODTIME#410

Open
7MS8 wants to merge 1 commit into
newhinton:masterfrom
7MS8:fix/rclone-local-no-set-modtime
Open

fix: stop forcing size-only sync comparisons via RCLONE_LOCAL_NO_SET_MODTIME#410
7MS8 wants to merge 1 commit into
newhinton:masterfrom
7MS8:fix/rclone-local-no-set-modtime

Conversation

@7MS8

@7MS8 7MS8 commented Jul 8, 2026

Copy link
Copy Markdown

Split out of #406 per reviewer request (separate unrelated fixes into their own PRs).

Bug

RCLONE_LOCAL_NO_SET_MODTIME=true has been set for every rclone invocation since 2021 (f43949be), to work around chtimes crashes on old Android storage stacks (rclone#2446). It has a much bigger side effect than intended: rclone's local backend Precision() reports fs.ModTimeNotSupported unconditionally whenever NoSetModTime is set (backend/local/local.go), and rclone's default file comparison treats ModTimeNotSupported as "always equal" as soon as file sizes match (fs/operations/operations.go) — modification-time comparison is skipped entirely. Every sync, regardless of remote type or --checksum, silently degrades to a same-size-means-unchanged check. Changed files that happen to keep the same size are never re-synced.

Fix

Verified in current rclone (v1.71.0, vendored in this repo) that a failing chtimes()/SetModTime is not fatal: fs/operations/operations.go just logs and counts the error, the transfer itself still succeeds. The 2021 workaround for the old crash is no longer needed and was silently breaking change detection instead. Remove RCLONE_LOCAL_NO_SET_MODTIME=true from both Rclone.java and RcloneRcd.java, letting rclone's own runtime precision probe handle it per-remote.

Reproduction

  • Any remote (tested against SFTP/Synology): sync a file once so source and destination match.
  • Edit the file so its size stays exactly the same but content and mtime change (e.g. flip one character).
  • Trigger sync again.
  • Before this fix: sync.log shows the file is skipped ("Sizes identical" / unchanged) — the change is never picked up.
  • After this fix: file is correctly detected as changed via modtime and re-transferred ("Copied (replaced existing)"); a subsequent sync then correctly no-ops.

Test plan

  • Verified end-to-end against a live Synology SFTP remote and on a physical Pixel 7a (GrapheneOS): same-size/changed-content file is now correctly detected and re-transferred, no chtimes errors logged, local mtime ends up matching the source.
  • Local build compiles (./gradlew :app:compileOssDebugSources).

…MODTIME

RCLONE_LOCAL_NO_SET_MODTIME=true has been set for every rclone
invocation since 2021 (f43949b) to avoid chtimes crashes on old
Android storage stacks (rclone#2446). It has a much bigger side
effect than intended: rclone's local backend Precision() reports
fs.ModTimeNotSupported unconditionally whenever NoSetModTime is set
(backend/local/local.go), and rclone's default file comparison
treats ModTimeNotSupported as "always equal" as soon as sizes match
(fs/operations/operations.go) -- skipping modification-time
comparison entirely. Every sync, regardless of remote type or
--checksum, silently degraded to a same-size-means-unchanged check.
Changed files that happened to keep the same size were never
re-synced.

Verified in current rclone (v1.71.0, vendored in this repo) that a
failing chtimes()/SetModTime is not fatal: fs/operations/operations.go
just logs and counts the error, the transfer itself still succeeds.
The 2021 workaround is no longer needed and was silently breaking
change detection instead.

Verified against a live Synology SFTP remote: a same-size,
content-changed file is now correctly detected via modtime and
re-transferred ("Copied (replaced existing)"), a second sync
correctly no-ops once the file is genuinely in sync, and the local
destination's mtime is now correctly set to match the source with no
chtimes errors logged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant