mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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:7428630b75("UFS: write inode block for fdatasync(2) if pointers in inode where allocated") Fixes:52488b5148("Further evaluation of the POSIX spec for fdatasync()...") Fixes:e7347be9e3("ffs: Support O_DSYNC.") Fixes:113db2dddb("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
This commit is contained in:
1 parent
2aca5deff7
commit
8ff663dde2
2 files changed
+3
-3
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user