A simple, high performance text editor.
Edits on the phone were not picked up by syncthing for minutes to hours
("edited a file, but it never synced to my other devices").
Reproduced on device (Pixel 9 Pro, API 35, Syncthing-Fork, shared
storage /storage/emulated/0):
- The app's temp+rename save lands the new content (inode changes,
bytes are correct), yet the file's mtime served through the FUSE
layer reverts to the PREVIOUS file's mtime -- exactly, to the
nanosecond. MediaProvider's media-scan DB row for the path is not
updated when the staging file is renamed into place (logcat:
"Database update failed while renaming .<name>.tmp.<pid>.<seq>")
and the stale row wins. This reproduces for ANY writer, not just
the app (shell temp+rename included).
- The fork's inotify watcher ignores these rename-based writes for a
long time (a 15:48 edit reached the peer only at 16:39; five
consecutive app writes over 6 minutes were never propagated), but
it acts on an explicit timestamp update immediately (a touch
synced in exactly the 10 s fsWatcherDelayS). Inotify events
themselves are delivered fine (verified with an on-device inotify
watcher: IN_MOVED_TO arrives).
Fix: after the rename in RealFileSystem.WriteFileAtomic, set the
file's atime/mtime to now (os.Chtimes, best-effort). utimensat
sticks through the FUSE layer and is the update the watcher reacts
to. Verified on device after the fix: edit -> peer in ~11-12 s,
mtime stays current.
Also pins the timestamp contract in
TestWriteFileAtomic_PublishesCurrentMtime (mtime is current after a
write and advances on rewrite) and documents the invariant in
architecture.md 6.5.
|
||
|---|---|---|
| .qwen | ||
| cmd/pad | ||
| doc | ||
| internal | ||
| scripts | ||
| tools/touchinject | ||
| .DS_Store | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||