[PATCH 1/4] btrfs: honor FMODE_NOCMTIME in btrfs_write_check()

From: Jeff Layton

Date: Thu Nov 05 2026 - 15:37:59 EST


btrfs_write_check() open-codes the c/mtime update and checks only
IS_NOCMTIME(inode). file_update_time() also skips the update when the
file has FMODE_NOCMTIME. nfsd sets this flag on files that have a
delegation with delegated timestamps.

Thus, on a btrfs export, WRITEs from the delegation holder update the
server's c/mtime. When the holder returns its times, nfsd restores the
mtime. nfsd cannot move ctime backward, so ctime stays newer than the
time that the holder reported. Over NFSv4.2, git test t1092 finds a
stat-dirty file.

Skip the update for FMODE_NOCMTIME files too.

Fixes: e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation")
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
fs/btrfs/file.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index f978c6524aa0..94475976d8cf 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1053,7 +1053,7 @@ int btrfs_write_check(struct kiocb *iocb, size_t count)
* need to start yet another transaction to update the inode as we will
* update the inode when we finish writing whatever data we write.
*/
- if (!IS_NOCMTIME(inode)) {
+ if (!IS_NOCMTIME(inode) && !(file->f_mode & FMODE_NOCMTIME)) {
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
inode_inc_iversion(inode);
}

--
2.56.0