diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-16 17:33:25 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-29 11:35:49 -0400 |
commit | c654b8a9cba6002aad1c01919e4928a79a4a6dcf (patch) | |
tree | fee411bb42ec86e72a9e843529551e559c1f2749 /include | |
parent | 3352d2c2d0540955a7bbb3421a28330af7f9d79c (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')
-rw-r--r-- | include/linux/nfsd/nfsfh.h | 7 | ||||
-rw-r--r-- | include/linux/nfsd/xdr4.h | 17 |
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 | ||
65 | struct nfsd4_change_info { | 65 | struct 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 | ||
73 | struct nfsd4_access { | 76 | struct 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 | ||
512 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); | 521 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); |