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/linux/nfsd | |
| 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/linux/nfsd')
| -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 *); |
