diff mbox series

nfs: always force a full attribute revalidation after NFSv4 writes

Message ID 20200519092753.13658-1-zhengbin13@huawei.com (mailing list archive)
State New, archived
Headers show
Series nfs: always force a full attribute revalidation after NFSv4 writes | expand

Commit Message

Zheng Bin May 19, 2020, 9:27 a.m. UTC
Use the following command to test nfsv4(size of file1M is 1MB):
mount -t nfs -o vers=4.0,actimeo=60 127.0.0.1/dir1 /mnt
cp file1M /mnt
du -h /mnt/file1M  -->0 within 60s, then 1M

When write is done(cp file1M /mnt), will call this:
nfs_writeback_done
  nfs4_write_done
    nfs4_write_done_cb
      nfs_writeback_update_inode
        nfs_post_op_update_inode_force_wcc_locked(change, ctime, mtime
nfs_post_op_update_inode_force_wcc_locked
   nfs_set_cache_invalid
   nfs_refresh_inode_locked
     nfs_update_inode

nfsd write response contains change, ctime, mtime, the flag will be
clear after nfs_update_inode. Howerver, write response does not contain
space_used, previous open response contains space_used whose value is 0,
so inode->i_blocks is still 0.

nfs_getattr  -->called by "du -h"
  do_update |= force_sync || nfs_attribute_cache_expired -->false in 60s
  cache_validity = READ_ONCE(NFS_I(inode)->cache_validity)
  do_update |= cache_validity & (NFS_INO_INVALID_ATTR    -->false
  if (do_update) {
	__nfs_revalidate_inode
  }

Within 60s, does not send getattr request to nfsd, thus "du -h /mnt/file1M"
is 0.

Fixes: 16e143751727 ("NFS: More fine grained attribute tracking")
Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
---
 fs/nfs/inode.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--
2.26.0.106.g9fadedd

Comments

Trond Myklebust May 19, 2020, 3:55 p.m. UTC | #1
On Tue, 2020-05-19 at 17:27 +0800, Zheng Bin wrote:
> Use the following command to test nfsv4(size of file1M is 1MB):
> mount -t nfs -o vers=4.0,actimeo=60 127.0.0.1/dir1 /mnt
> cp file1M /mnt
> du -h /mnt/file1M  -->0 within 60s, then 1M
> 
> When write is done(cp file1M /mnt), will call this:
> nfs_writeback_done
>   nfs4_write_done
>     nfs4_write_done_cb
>       nfs_writeback_update_inode
>         nfs_post_op_update_inode_force_wcc_locked(change, ctime,
> mtime
> nfs_post_op_update_inode_force_wcc_locked
>    nfs_set_cache_invalid
>    nfs_refresh_inode_locked
>      nfs_update_inode
> 
> nfsd write response contains change, ctime, mtime, the flag will be
> clear after nfs_update_inode. Howerver, write response does not
> contain
> space_used, previous open response contains space_used whose value is
> 0,
> so inode->i_blocks is still 0.
> 
> nfs_getattr  -->called by "du -h"
>   do_update |= force_sync || nfs_attribute_cache_expired -->false in
> 60s
>   cache_validity = READ_ONCE(NFS_I(inode)->cache_validity)
>   do_update |= cache_validity & (NFS_INO_INVALID_ATTR    -->false
>   if (do_update) {
> 	__nfs_revalidate_inode
>   }
> 
> Within 60s, does not send getattr request to nfsd, thus "du -h
> /mnt/file1M"
> is 0.
> 
> Fixes: 16e143751727 ("NFS: More fine grained attribute tracking")
> Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
> ---
>  fs/nfs/inode.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> index b9d0921cb4fe..bdfb98d5f45b 100644
> --- a/fs/nfs/inode.c
> +++ b/fs/nfs/inode.c
> @@ -1764,7 +1764,8 @@ int
> nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct
> nfs_fa
>  	status = nfs_post_op_update_inode_locked(inode, fattr,
>  			NFS_INO_INVALID_CHANGE
>  			| NFS_INO_INVALID_CTIME
> -			| NFS_INO_INVALID_MTIME);
> +			| NFS_INO_INVALID_MTIME
> +			| NFS_INO_INVALID_OTHER);
>  	return status;
>  }
> 

NACK. Please add a NFS_INO_INVALID_BLOCKS for this case instead of
setting INVALID_OTHER.

Quite frankly, "space used" is an anachronism from the days when
everything was stored on local disk on your workstation, before the
days of automated tiering, dedup and/or compression. It should not
matter to applications and so we definitely want to be able to optimise
it away in statx() calls that don't explicitly ask for it.
diff mbox series

Patch

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b9d0921cb4fe..bdfb98d5f45b 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1764,7 +1764,8 @@  int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fa
 	status = nfs_post_op_update_inode_locked(inode, fattr,
 			NFS_INO_INVALID_CHANGE
 			| NFS_INO_INVALID_CTIME
-			| NFS_INO_INVALID_MTIME);
+			| NFS_INO_INVALID_MTIME
+			| NFS_INO_INVALID_OTHER);
 	return status;
 }