aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-04-16 17:33:25 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-04-29 11:35:49 -0400
commitc654b8a9cba6002aad1c01919e4928a79a4a6dcf (patch)
treefee411bb42ec86e72a9e843529551e559c1f2749 /include/linux/nfsd
parent3352d2c2d0540955a7bbb3421a28330af7f9d79c (diff)
nfsd: support ext4 i_version
ext4 supports a real NFSv4 change attribute, which is bumped whenever the ctime would be updated, including times when two updates arrive within a jiffy of each other. (Note that although ext4 has space for nanosecond-precision ctime, the real resolution is lower: it actually uses jiffies as the time-source.) This ensures clients will invalidate their caches when they need to. There is some fear that keeping the i_version up-to-date could have performance drawbacks, so for now it's turned on only by a mount option. We hope to do something better eventually. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Cc: Theodore Tso <tytso@mit.edu>
Diffstat (limited to 'include/linux/nfsd')
-rw-r--r--include/linux/nfsd/nfsfh.h7
-rw-r--r--include/linux/nfsd/xdr4.h17
2 files changed, 20 insertions, 4 deletions
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index afa19016c4a8..8f641c908450 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -151,9 +151,15 @@ typedef struct svc_fh {
151 __u64 fh_pre_size; /* size before operation */ 151 __u64 fh_pre_size; /* size before operation */
152 struct timespec fh_pre_mtime; /* mtime before oper */ 152 struct timespec fh_pre_mtime; /* mtime before oper */
153 struct timespec fh_pre_ctime; /* ctime before oper */ 153 struct timespec fh_pre_ctime; /* ctime before oper */
154 /*
155 * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
156 * to find out if it is valid.
157 */
158 u64 fh_pre_change;
154 159
155 /* Post-op attributes saved in fh_unlock */ 160 /* Post-op attributes saved in fh_unlock */
156 struct kstat fh_post_attr; /* full attrs after operation */ 161 struct kstat fh_post_attr; /* full attrs after operation */
162 u64 fh_post_change; /* nfsv4 change; see above */
157#endif /* CONFIG_NFSD_V3 */ 163#endif /* CONFIG_NFSD_V3 */
158 164
159} svc_fh; 165} svc_fh;
@@ -298,6 +304,7 @@ fill_pre_wcc(struct svc_fh *fhp)
298 fhp->fh_pre_mtime = inode->i_mtime; 304 fhp->fh_pre_mtime = inode->i_mtime;
299 fhp->fh_pre_ctime = inode->i_ctime; 305 fhp->fh_pre_ctime = inode->i_ctime;
300 fhp->fh_pre_size = inode->i_size; 306 fhp->fh_pre_size = inode->i_size;
307 fhp->fh_pre_change = inode->i_version;
301 fhp->fh_pre_saved = 1; 308 fhp->fh_pre_saved = 1;
302 } 309 }
303} 310}
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index f80d6013fdc3..d0f050f01eca 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -64,10 +64,13 @@ static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
64 64
65struct nfsd4_change_info { 65struct nfsd4_change_info {
66 u32 atomic; 66 u32 atomic;
67 bool change_supported;
67 u32 before_ctime_sec; 68 u32 before_ctime_sec;
68 u32 before_ctime_nsec; 69 u32 before_ctime_nsec;
70 u64 before_change;
69 u32 after_ctime_sec; 71 u32 after_ctime_sec;
70 u32 after_ctime_nsec; 72 u32 after_ctime_nsec;
73 u64 after_change;
71}; 74};
72 75
73struct nfsd4_access { 76struct nfsd4_access {
@@ -503,10 +506,16 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
503{ 506{
504 BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); 507 BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
505 cinfo->atomic = 1; 508 cinfo->atomic = 1;
506 cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; 509 cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
507 cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; 510 if (cinfo->change_supported) {
508 cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; 511 cinfo->before_change = fhp->fh_pre_change;
509 cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; 512 cinfo->after_change = fhp->fh_post_change;
513 } else {
514 cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
515 cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
516 cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
517 cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
518 }
510} 519}
511 520
512int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); 521int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);