[PATCH] NFS: invalidate i_blocks after COMMIT to fix stale block count on NFSv4

Jingbo Xu <jefflexu-KPsoFbNs7GizrGE5bRqYAgC/[email protected]>
Newsgroups gmane.linux.nfs,gmane.linux.kernel
Message-ID <[email protected]>
NFSv4 COMMIT compound does not include GETATTR, and nfs4_commit_done_cb
does not refresh inode attributes. Meanwhile, every WRITE marks
NFS_INO_INVALID_BLOCKS via nfs_post_op_update_inode_force_wcc_locked.

After COMMIT, i_blocks remains stale until the next stat() triggers a
full revalidation. In writeback-heavy workloads where COMMITs happen
without intervening stat() calls, the cached block count can stay
indefinitely wrong.

Mark NFS_INO_INVALID_BLOCKS on successful COMMIT completion so that the
next nfs_getattr requesting STATX_BLOCKS will issue a GETATTR with
SPACE_USED, fetching the correct value from the server.

This matches NFSv3 behavior where nfs3_commit_done already calls
nfs_refresh_inode with the wcc_data post-op attributes.

Reproduce with xfstests generic/694 on NFSv4.0 loopback:

  Server:
    mount /dev/vdc /data/test
    mount /dev/vdd /data/scratch
    exportfs -o insecure,rw,sync,no_root_squash,fsid=1 127.0.0.1:/data/test
    exportfs -o insecure,rw,sync,no_root_squash,fsid=2 127.0.0.1:/data/scratch

  Client:
    mount -t nfs -o vers=4.0 localhost:/data/test /mnt/test
    mount -t nfs -o vers=4.0 localhost:/data/scratch /mnt/scratch

  local.config:
    export TEST_FS_MOUNT_OPTS="-o vers=4.0"
    export MOUNT_OPTIONS="-o vers=4.0"
    export FSTYP=nfs
    export TEST_DEV=localhost:/data/test
    export SCRATCH_DEV=localhost:/data/scratch
    export TEST_DIR=/mnt/test
    export SCRATCH_MNT=/mnt/scratch

This fixes xfstests generic/694.

Assisted-by: Qoder:Qwen3.7-Max
Signed-off-by: Jingbo Xu <jefflexu-KPsoFbNs7GizrGE5bRqYAgC/[email protected]>
---
 fs/nfs/write.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index d7c399763ad9..88c5c9f7434c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1851,6 +1851,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
 		/* Latency breaker */
 		cond_resched();
 	}
+	if (status >= 0)
+		nfs_set_cache_invalid(data->inode, NFS_INO_INVALID_BLOCKS);
 
 	nfs_init_cinfo(&cinfo, data->inode, data->dreq);
 	nfs_commit_end(cinfo.mds);
-- 
2.19.1.6.gb485710b
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.