summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2024-06-16 21:21:31 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2024-07-08 13:47:25 -0400
commit32215c1f893a11c5b0c6e1d70907cb40b54925ab (patch)
tree0da72e2b49a20b9c1effdfcc75ce43c04f2f48a9
parent0a741f59c331254a2fc7eb57cfdd25e75c2ce48f (diff)
downloadlwn-32215c1f893a11c5b0c6e1d70907cb40b54925ab.tar.gz
lwn-32215c1f893a11c5b0c6e1d70907cb40b54925ab.zip
NFSv4: Don't request atime/mtime/size if they are delegated to us
If the timestamps and size are delegated to the client, then it is authoritative w.r.t. their values, so we should not be requesting those values from the server. Note that this allows us to optimise away most GETATTR calls if the only changes to the attributes are the result of read() or write(). Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Lance Shelton <lance.shelton@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 88edeaf5b5d5..cbd340cd825e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -310,6 +310,18 @@ static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src,
dst[1] &= ~FATTR4_WORD1_MODE;
if (!(cache_validity & NFS_INO_INVALID_OTHER))
dst[1] &= ~(FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP);
+
+ if (nfs_have_delegated_mtime(inode)) {
+ if (!(cache_validity & NFS_INO_INVALID_ATIME))
+ dst[1] &= ~FATTR4_WORD1_TIME_ACCESS;
+ if (!(cache_validity & NFS_INO_INVALID_MTIME))
+ dst[1] &= ~FATTR4_WORD1_TIME_MODIFY;
+ if (!(cache_validity & NFS_INO_INVALID_CTIME))
+ dst[1] &= ~FATTR4_WORD1_TIME_METADATA;
+ } else if (nfs_have_delegated_atime(inode)) {
+ if (!(cache_validity & NFS_INO_INVALID_ATIME))
+ dst[1] &= ~FATTR4_WORD1_TIME_ACCESS;
+ }
}
static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
@@ -3414,7 +3426,8 @@ static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
.inode = inode,
.stateid = &arg.stateid,
};
- unsigned long adjust_flags = NFS_INO_INVALID_CHANGE;
+ unsigned long adjust_flags = NFS_INO_INVALID_CHANGE |
+ NFS_INO_INVALID_CTIME;
int err;
if (sattr->ia_valid & (ATTR_MODE | ATTR_KILL_SUID | ATTR_KILL_SGID))
@@ -4978,8 +4991,9 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
goto out;
nfs4_inode_make_writeable(inode);
- nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.fattr->label), inode,
- NFS_INO_INVALID_CHANGE);
+ nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.fattr->label),
+ inode,
+ NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME);
status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
if (!status) {
nfs4_update_changeattr(dir, &res.cinfo, res.fattr->time_start,