From: Dai Ngo Date: Thu, 23 Apr 2026 17:52:10 +0000 (-0700) Subject: NFS: fix eof updates after NFSv4.2 fallocate/zero-range X-Git-Tag: v7.2-rc1~46^2~31 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=35168eb947f230aaa35fd8416a30563ef89f5421;p=thirdparty%2Fkernel%2Flinux.git NFS: fix eof updates after NFSv4.2 fallocate/zero-range Generic/075 reliably exposes a regression when the client holds an NFSv4 write delegation: ZERO_RANGE/ALLOCATE extends the file on the server, but the local inode keeps the old i_size. The test then fails with 'Size error' because the post-op attribute refresh refuses to touch i_size while a delegation is outstanding, and the cached EOF was never marked stale. Update _nfs42_proc_fallocate() so that on success it: - bumps i_size when the operation extends the file, and - marks NFS_INO_INVALID_BLOCKS since the block count can also change Tested with xfstests generic/075 over NFSv4.2. Signed-off-by: Dai Ngo Signed-off-by: Anna Schumaker --- diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 7602ede6f75f7..ab86246fc364f 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -81,12 +81,17 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, status = nfs4_call_sync(server->client, server, msg, &args.seq_args, &res.seq_res, 0); if (status == 0) { - if (nfs_should_remove_suid(inode)) { - spin_lock(&inode->i_lock); + loff_t newsize = offset + len; + + spin_lock(&inode->i_lock); + if (newsize > i_size_read(inode)) + i_size_write(inode, newsize); + nfs_set_cache_invalid(inode, NFS_INO_INVALID_BLOCKS); + if (nfs_should_remove_suid(inode)) nfs_set_cache_invalid(inode, - NFS_INO_REVAL_FORCED | NFS_INO_INVALID_MODE); - spin_unlock(&inode->i_lock); - } + NFS_INO_REVAL_FORCED | + NFS_INO_INVALID_MODE); + spin_unlock(&inode->i_lock); status = nfs_post_op_update_inode_force_wcc(inode, res.falloc_fattr); }