nfs: set invalid blocks after NFSv4 writes
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.
Add a NFS_INO_INVALID_BLOCKS flag, set it when nfsv4 write is done.
Fixes: 16e1437517
("NFS: More fine grained attribute tracking")
Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
86b936672e
commit
3a39e77869
@ -833,6 +833,8 @@ int nfs_getattr(const struct path *path, struct kstat *stat,
|
||||
do_update |= cache_validity & NFS_INO_INVALID_ATIME;
|
||||
if (request_mask & (STATX_CTIME|STATX_MTIME))
|
||||
do_update |= cache_validity & NFS_INO_REVAL_PAGECACHE;
|
||||
if (request_mask & STATX_BLOCKS)
|
||||
do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
|
||||
if (do_update) {
|
||||
/* Update the attribute cache */
|
||||
if (!(server->flags & NFS_MOUNT_NOAC))
|
||||
@ -1764,7 +1766,8 @@ out_noforce:
|
||||
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_BLOCKS);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1871,7 +1874,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR
|
||||
| NFS_INO_INVALID_ATIME
|
||||
| NFS_INO_REVAL_FORCED
|
||||
| NFS_INO_REVAL_PAGECACHE);
|
||||
| NFS_INO_REVAL_PAGECACHE
|
||||
| NFS_INO_INVALID_BLOCKS);
|
||||
|
||||
/* Do atomic weak cache consistency updates */
|
||||
nfs_wcc_update_inode(inode, fattr);
|
||||
@ -2033,8 +2037,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||
inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
|
||||
} else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
|
||||
inode->i_blocks = fattr->du.nfs2.blocks;
|
||||
else
|
||||
else {
|
||||
nfsi->cache_validity |= save_cache_validity &
|
||||
(NFS_INO_INVALID_BLOCKS
|
||||
| NFS_INO_REVAL_FORCED);
|
||||
cache_revalidated = false;
|
||||
}
|
||||
|
||||
/* Update attrtimeo value if we're out of the unstable period */
|
||||
if (attr_changed) {
|
||||
|
@ -230,6 +230,7 @@ struct nfs4_copy_state {
|
||||
#define NFS_INO_INVALID_OTHER BIT(12) /* other attrs are invalid */
|
||||
#define NFS_INO_DATA_INVAL_DEFER \
|
||||
BIT(13) /* Deferred cache invalidation */
|
||||
#define NFS_INO_INVALID_BLOCKS BIT(14) /* cached blocks are invalid */
|
||||
|
||||
#define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
|
||||
| NFS_INO_INVALID_CTIME \
|
||||
|
Loading…
Reference in New Issue
Block a user