git: 8ff663dde22f - main - ufs: make fdatasync(2) and O_DSYNC writes update the inode
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 13 Oct 2026 04:29:52 UTC
The branch main has been updated by sobomax:
URL: https://cgit.FreeBSD.org/src/commit/?id=8ff663dde22fe9f50ba5d71d0237bec9b9b44683
commit 8ff663dde22fe9f50ba5d71d0237bec9b9b44683
Author: Maxim Sobolev <sobomax@FreeBSD.org>
AuthorDate: 2026-10-13 02:39:05 +0000
Commit: Maxim Sobolev <sobomax@FreeBSD.org>
CommitDate: 2026-10-13 04:28:32 +0000
ufs: make fdatasync(2) and O_DSYNC writes update the inode
ffs_syncvnode() in the DATA_ONLY case and ffs_write() for IO_DATASYNC
decide whether the inode has to be written by testing IN_SIZEMOD and
IN_IBLKDATA against ip->i_flags, the chflags(2) word, instead of the
in-core state ip->i_flag. IN_SIZEMOD and IN_IBLKDATA alias UF_READONLY
and UF_ARCHIVE, so for ordinary files the test was always false: after
an fdatasync() or an O_DSYNC write that extended a file or filled a
hole, the data blocks were on disk but the inode size and block pointers
were not, and a crash before the syncer got to the inode lost the
"synced" data. Files with uarchive or urdonly set got a synchronous
inode write on every call instead.
journal_mount() has the same mixup and sets IN_MODIFIED in i_flags,
which leaves UF_OPAQUE set on the in-core .sujournal inode. The
synchronous ffs_update() that follows writes the inode regardless, so
only the stray flag is fixed here.
Fixes: 7428630b757 ("UFS: write inode block for fdatasync(2) if pointers in inode where allocated")
Fixes: 52488b51489 ("Further evaluation of the POSIX spec for fdatasync()...")
Fixes: e7347be9e34 ("ffs: Support O_DSYNC.")
Fixes: 113db2dddb7 ("Merge soft-updates journaling from projects/suj/head into head.")
Sponsored by: Sippy Software, Inc.
Reviewed by: kib
Tested by: pho
Differential Revision: https://reviews.freebsd.org/D60134
MFC after: 1 month
---
sys/ufs/ffs/ffs_softdep.c | 2 +-
sys/ufs/ffs/ffs_vnops.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index a83f7ee9b91c..a7068f43a800 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -2976,7 +2976,7 @@ journal_mount(struct mount *mp,
*/
if (fs->fs_clean) {
DIP_SET(ip, i_modrev, fs->fs_mtime);
- ip->i_flags |= IN_MODIFIED;
+ ip->i_flag |= IN_MODIFIED;
ffs_update(vp, 1);
}
out:
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index ee495fe3888c..be708d07a2ca 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -458,7 +458,7 @@ next_locked:
error = ffs_update(vp, 1);
if (DOINGSUJ(vp))
softdep_journal_fsync(VTOI(vp));
- } else if ((ip->i_flags & (IN_SIZEMOD | IN_IBLKDATA)) != 0) {
+ } else if ((ip->i_flag & (IN_SIZEMOD | IN_IBLKDATA)) != 0) {
error = ffs_update(vp, 1);
}
if (error == 0 && unlocked)
@@ -1044,7 +1044,7 @@ ffs_write(
}
} else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
if (!(ioflag & IO_DATASYNC) ||
- (ip->i_flags & (IN_SIZEMOD | IN_IBLKDATA)))
+ (ip->i_flag & (IN_SIZEMOD | IN_IBLKDATA)))
error = ffs_update(vp, 1);
if (ffs_fsfail_cleanup(VFSTOUFS(vp->v_mount), error))
error = ENXIO;