]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
xfs: port xfs_ioc_start_commit to multigrain timestamps
authorDarrick J. Wong <djwong@kernel.org>
Mon, 2 Dec 2024 18:58:11 +0000 (10:58 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 13 Dec 2024 01:45:13 +0000 (17:45 -0800)
Take advantage of the multigrain timestamp APIs to ensure that nobody
can sneak in and write things to a file between starting a file update
operation and committing the results.  This should have been part of the
multigrain timestamp merge, but I forgot to fling it at jlayton when he
resubmitted the patchset due to developer bandwidth problems.

Cc: <stable@vger.kernel.org> # v6.13-rc1
Fixes: 4e40eff0b5737c ("fs: add infrastructure for multigrain timestamps")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
fs/xfs/xfs_exchrange.c

index 9ab05ad224d1273793b8d0201b092cfe448d2b7b..265c424498933e99f2224a84e0f96f7e834e97cd 100644 (file)
@@ -854,7 +854,7 @@ xfs_ioc_start_commit(
        struct xfs_commit_range __user  *argp)
 {
        struct xfs_commit_range         args = { };
-       struct timespec64               ts;
+       struct kstat                    kstat = { };
        struct xfs_commit_range_fresh   *kern_f;
        struct xfs_commit_range_fresh   __user *user_f;
        struct inode                    *inode2 = file_inode(file);
@@ -871,12 +871,12 @@ xfs_ioc_start_commit(
        memcpy(&kern_f->fsid, ip2->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
 
        xfs_ilock(ip2, lockflags);
-       ts = inode_get_ctime(inode2);
-       kern_f->file2_ctime             = ts.tv_sec;
-       kern_f->file2_ctime_nsec        = ts.tv_nsec;
-       ts = inode_get_mtime(inode2);
-       kern_f->file2_mtime             = ts.tv_sec;
-       kern_f->file2_mtime_nsec        = ts.tv_nsec;
+       /* Force writing of a distinct ctime if any writes happen. */
+       fill_mg_cmtime(&kstat, STATX_CTIME | STATX_MTIME, inode2);
+       kern_f->file2_ctime             = kstat.ctime.tv_sec;
+       kern_f->file2_ctime_nsec        = kstat.ctime.tv_nsec;
+       kern_f->file2_mtime             = kstat.mtime.tv_sec;
+       kern_f->file2_mtime_nsec        = kstat.mtime.tv_nsec;
        kern_f->file2_ino               = ip2->i_ino;
        kern_f->file2_gen               = inode2->i_generation;
        kern_f->magic                   = XCR_FRESH_MAGIC;