diff options
author | Jeff Layton <jlayton@kernel.org> | 2022-10-05 12:26:41 +0200 |
---|---|---|
committer | Jeff Layton <jlayton@kernel.org> | 2023-01-26 13:00:06 +0100 |
commit | 3139b1d79588f65977b3543149df01063dc3d323 (patch) | |
tree | 36b2431a643e75416527526864d6d0d77f1eab28 /fs/nfsd/nfsfh.c | |
parent | ceph: report the inode version in getattr if requested (diff) | |
download | linux-3139b1d79588f65977b3543149df01063dc3d323.tar.xz linux-3139b1d79588f65977b3543149df01063dc3d323.zip |
nfsd: move nfsd4_change_attribute to nfsfh.c
This is a pretty big function for inlining. Move it to being
non-inlined.
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/nfsfh.c')
-rw-r--r-- | fs/nfsd/nfsfh.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 8c52b6c9d31a..ac89e25e7733 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -748,3 +748,30 @@ enum fsid_source fsid_source(const struct svc_fh *fhp) return FSIDSOURCE_UUID; return FSIDSOURCE_DEV; } + +/* + * We could use i_version alone as the change attribute. However, + * i_version can go backwards after a reboot. On its own that doesn't + * necessarily cause a problem, but if i_version goes backwards and then + * is incremented again it could reuse a value that was previously used + * before boot, and a client who queried the two values might + * incorrectly assume nothing changed. + * + * By using both ctime and the i_version counter we guarantee that as + * long as time doesn't go backwards we never reuse an old value. + */ +u64 nfsd4_change_attribute(struct kstat *stat, struct inode *inode) +{ + if (inode->i_sb->s_export_op->fetch_iversion) + return inode->i_sb->s_export_op->fetch_iversion(inode); + else if (IS_I_VERSION(inode)) { + u64 chattr; + + chattr = stat->ctime.tv_sec; + chattr <<= 30; + chattr += stat->ctime.tv_nsec; + chattr += inode_query_iversion(inode); + return chattr; + } else + return time_to_chattr(&stat->ctime); +} |