Skip to content

sync: fsync() file operands when no -d/-f flags (GNU MODE_FILE compat) - #14592

Open
lostallmymoney wants to merge 2 commits into
uutils:mainfrom
lostallmymoney:fix-sync-fsync-file-operands
Open

lostallmymoney wants to merge 2 commits into
uutils:mainfrom
lostallmymoney:fix-sync-fsync-file-operands

Conversation

@lostallmymoney

Copy link
Copy Markdown

With file operands and no --data/-d or --file-system/-f flag, GNU sync enters MODE_FILE and fsync()s each operand. uutils instead falls through to a global sync(), silently ignoring the operands and blocking on every filesystem behind initramfs/dracut. Add an fsync(2) path (Linux/Android) mirroring do_fdatasync, and a regression test using /proc/self/mem which rejects fsync() with EINVAL (a global sync() would wrongly exit 0).

Fixes: #14591

@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/misc/sync. tests/misc/sync is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/misc/io-errors (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/pid-pipe (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/cp/cp-mv-enotsup-xattr is no longer failing!
Congrats! The gnu test tests/date/date-tz is no longer failing!
Congrats! The gnu test tests/dd/nocache is no longer failing!
Congrats! The gnu test tests/df/skip-rootfs is no longer failing!
Congrats! The gnu test tests/env/env is no longer failing!
Congrats! The gnu test tests/id/setgid is no longer failing!
Congrats! The gnu test tests/id/smack is no longer failing!
Congrats! The gnu test tests/join/join is no longer failing!
Congrats! The gnu test tests/ls/ls-time is no longer failing!
Congrats! The gnu test tests/misc/printenv is no longer failing!
Congrats! The gnu test tests/mkdir/smack-root is no longer failing!
Congrats! The gnu test tests/mv/mv-special-1 is no longer failing!
Congrats! The gnu test tests/od/od is no longer failing!
Congrats! The gnu test tests/ptx/ptx is no longer failing!
Congrats! The gnu test tests/shred/shred-remove is no longer failing!
Congrats! The gnu test tests/sort/sort is no longer failing!
Congrats! The gnu test tests/split/split-io-err is no longer failing!
Congrats! The gnu test tests/stat/stat-fmt is no longer failing!
Congrats! The gnu test tests/stat/stat-nanoseconds is no longer failing!
Congrats! The gnu test tests/test/test is no longer failing!
Congrats! The gnu test tests/touch/now-owned-by-other is no longer failing!
Congrats! The gnu test tests/wc/wc is no longer failing!
Note: The gnu test tests/basenc/bounded-memory is now being skipped but was previously passing.
Note: The gnu test tests/rm/many-dir-entries-vs-OOM is now being skipped but was previously passing.
Note: The gnu test tests/misc/getopt_vs_usage was skipped on 'main' but is now failing.
Note: The gnu test tests/misc/usage_vs_refs was skipped on 'main' but is now failing.

Comment thread tests/by-util/test_sync.rs Outdated
@lostallmymoney
lostallmymoney force-pushed the fix-sync-fsync-file-operands branch from bb3bc91 to 466fb2b Compare September 16, 2026 19:09
@lostallmymoney

This comment was marked as off-topic.

Comment thread src/uu/sync/src/sync.rs
#[cfg(any(target_os = "linux", target_os = "android"))]
fdatasync(&files)?;
} else if !files.is_empty() {
#[cfg(any(target_os = "linux", target_os = "android"))]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We probably should keep sync fallback on other targets.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We could remove this cfg using std::fs::File::sync_data instead of rustix. I'm working on it at #15733 .

@sylvestre

Copy link
Copy Markdown
Contributor

the CI has been failing on this one for a while, could you please have a look? otherwise, i will close it, thanks

@lostallmymoney

Copy link
Copy Markdown
Author

the CI has been failing on this one for a while, could you please have a look? otherwise, i will close it, thanks

Hey pardon me, I am out of my universe here. I know the fix isn't big and is for a missing feature (file sync which started doing global syncs since rust utils, one error on drive B prevented initramfs generation from syncing on drive A).
I wouldn't want to mess anything up, I do not know much about the process of contributing to linux projects.

oech3's comment intrigues me and I do not know the specifics of the targets, I wouldn't want to dirty it up.
I believe it's the test which is failing, and that someone with more knowledge should validate the small fix (reintroducing the ability to sync uniquely the file passed as argument).

The test tries to sync and unsync'able file, and fails, which is the way we know it doesn't try to sync the full drive instead. It shouldn't be necessary but would be an indicator of the feature loss coming back. I do not know what environment the test runs on, and if this test is dependant on the environment then I'm not even sure it should be there or under that shape. Thanks !

fn test_sync_file_operands_fsync_each_file() {
// Regression test: `sync FILE` (no -d/-f flags) must fsync each file
// like GNU coreutils, not fall back to a global sync() that ignores
// the operands. /proc/self/mem rejects fsync() with EINVAL, so this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
// the operands. /proc/self/mem rejects fsync() with EINVAL, so this
// the operands. /dev/null rejects fsync() with EINVAL, so this

ccmsi and others added 2 commits October 25, 2026 09:47
With file operands and no --data/-d or --file-system/-f flag, GNU sync enters MODE_FILE and fsync()s each operand. uutils instead falls through to a global sync(), silently ignoring the operands and blocking on every filesystem behind initramfs/dracut. Add an fsync(2) path (Linux/Android) mirroring do_fdatasync, and a regression test using /proc/self/mem which rejects fsync() with EINVAL (a global sync() would wrongly exit 0).

Fixes: uutils#14591
Co-authored-by: oech3 <79379754+oech3@users.noreply.github.com>
@sylvestre
sylvestre force-pushed the fix-sync-fsync-file-operands branch from a533597 to e8d02e5 Compare October 25, 2026 08:47

This branch has not been deployed

No deployments
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.

sync FILE hangs because of a USB disk I/O errors, applies global sync for no apparent reasons.

3 participants