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

Trond Myklebust <[email protected]>
Newsgroups gmane.linux.nfs,gmane.linux.kernel
Message-ID <[email protected]>
On Mon, 2026-06-22 at 14:00 +0800, Jingbo Xu wrote:
> 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);

That sounds like an XFS bug, not an NFS bug. COMMIT isn't changing the
data contents of the file: it is just ensuring that the existing data
is persisted onto disk.

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
[email protected], trond.myklebust-F/[email protected]
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.