summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.h
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2022-09-07 14:45:01 -0400
committerJeff Layton <jlayton@kernel.org>2023-01-26 07:00:06 -0500
commit638e3e7d9493dadca16cac7ea66e7cf368d4065a (patch)
treef44218cb65a1f9147c0b17cd2065b6acad074111 /fs/nfsd/vfs.h
parent3139b1d79588f65977b3543149df01063dc3d323 (diff)
downloadlinux-stable-638e3e7d9493dadca16cac7ea66e7cf368d4065a.tar.gz
linux-stable-638e3e7d9493dadca16cac7ea66e7cf368d4065a.tar.bz2
linux-stable-638e3e7d9493dadca16cac7ea66e7cf368d4065a.zip
nfsd: use the getattr operation to fetch i_version
Now that we can call into vfs_getattr to get the i_version field, use that facility to fetch it instead of doing it in nfsd4_change_attribute. Neil also pointed out recently that IS_I_VERSION directory operations are always logged, and so we only need to mitigate the rollback problem on regular files. Also, we don't need to factor in the ctime when reexporting NFS or Ceph. Set the STATX_CHANGE_COOKIE (and BTIME) bits in the request when we're dealing with a v4 request. Then, instead of looking at IS_I_VERSION when generating the change attr, look at the result mask and only use it if STATX_CHANGE_COOKIE is set. Change nfsd4_change_attribute to only factor in the ctime if it's a regular file and the fs doesn't advertise STATX_ATTR_CHANGE_MONOTONIC. Acked-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: NeilBrown <neilb@suse.de> Signed-off-by: Jeff Layton <jlayton@kernel.org>
Diffstat (limited to 'fs/nfsd/vfs.h')
-rw-r--r--fs/nfsd/vfs.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index dbdfef7ae85b..43fb57a301d3 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -170,9 +170,14 @@ static inline void fh_drop_write(struct svc_fh *fh)
static inline __be32 fh_getattr(const struct svc_fh *fh, struct kstat *stat)
{
+ u32 request_mask = STATX_BASIC_STATS;
struct path p = {.mnt = fh->fh_export->ex_path.mnt,
.dentry = fh->fh_dentry};
- return nfserrno(vfs_getattr(&p, stat, STATX_BASIC_STATS,
+
+ if (fh->fh_maxsize == NFS4_FHSIZE)
+ request_mask |= (STATX_BTIME | STATX_CHANGE_COOKIE);
+
+ return nfserrno(vfs_getattr(&p, stat, request_mask,
AT_STATX_SYNC_AS_STAT));
}