Commit 833221da authored by Neil Brown's avatar Neil Brown Committed by James Bottomley

[PATCH] Make kNFSd pre/post_[acm]time use struct timespec

From Trond:

  When the nanosecond resolution on [acm]time was introduced to 2.5.x,
the knfsd GETATTR responses were converted to make use of the
nanosecond field, but the pre/post WCC attributes were not. This will
lead to a lot of unnecessary cache invalidations on the clients.

The following trivial patch should fix up knfsd so that it stores and
encodes the full 'struct timespec' in both pre and post attribute
fields.
parent 696c47a2
...@@ -202,7 +202,6 @@ encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) ...@@ -202,7 +202,6 @@ encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
static inline u32 * static inline u32 *
encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
{ {
struct timespec time;
struct inode *inode = fhp->fh_dentry->d_inode; struct inode *inode = fhp->fh_dentry->d_inode;
/* Attributes to follow */ /* Attributes to follow */
...@@ -228,13 +227,9 @@ encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) ...@@ -228,13 +227,9 @@ encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
else else
p = xdr_encode_hyper(p, (u64) inode->i_sb->s_dev); p = xdr_encode_hyper(p, (u64) inode->i_sb->s_dev);
p = xdr_encode_hyper(p, (u64) inode->i_ino); p = xdr_encode_hyper(p, (u64) inode->i_ino);
time.tv_sec = fhp->fh_post_atime; p = encode_time3(p, &fhp->fh_post_atime);
time.tv_nsec = 0; p = encode_time3(p, &fhp->fh_post_mtime);
p = encode_time3(p, &time); p = encode_time3(p, &fhp->fh_post_ctime);
time.tv_sec = fhp->fh_post_mtime;
p = encode_time3(p, &time);
time.tv_sec = fhp->fh_post_ctime;
p = encode_time3(p, &time);
return p; return p;
} }
...@@ -266,14 +261,10 @@ encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) ...@@ -266,14 +261,10 @@ encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
if (dentry && dentry->d_inode && fhp->fh_post_saved) { if (dentry && dentry->d_inode && fhp->fh_post_saved) {
if (fhp->fh_pre_saved) { if (fhp->fh_pre_saved) {
struct timespec time;
*p++ = xdr_one; *p++ = xdr_one;
p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size); p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size);
time.tv_nsec = 0; p = encode_time3(p, &fhp->fh_pre_mtime);
time.tv_sec = fhp->fh_pre_mtime; p = encode_time3(p, &fhp->fh_pre_ctime);
p = encode_time3(p, &time);
time.tv_sec = fhp->fh_pre_ctime;
p = encode_time3(p, &time);
} else { } else {
*p++ = xdr_zero; *p++ = xdr_zero;
} }
......
...@@ -165,8 +165,8 @@ typedef struct svc_fh { ...@@ -165,8 +165,8 @@ typedef struct svc_fh {
/* Pre-op attributes saved during fh_lock */ /* Pre-op attributes saved during fh_lock */
__u64 fh_pre_size; /* size before operation */ __u64 fh_pre_size; /* size before operation */
time_t fh_pre_mtime; /* mtime before oper */ struct timespec fh_pre_mtime; /* mtime before oper */
time_t fh_pre_ctime; /* ctime before oper */ struct timespec fh_pre_ctime; /* ctime before oper */
/* Post-op attributes saved in fh_unlock */ /* Post-op attributes saved in fh_unlock */
umode_t fh_post_mode; /* i_mode */ umode_t fh_post_mode; /* i_mode */
...@@ -177,9 +177,9 @@ typedef struct svc_fh { ...@@ -177,9 +177,9 @@ typedef struct svc_fh {
unsigned long fh_post_blocks; /* i_blocks */ unsigned long fh_post_blocks; /* i_blocks */
unsigned long fh_post_blksize;/* i_blksize */ unsigned long fh_post_blksize;/* i_blksize */
__u32 fh_post_rdev[2];/* i_rdev */ __u32 fh_post_rdev[2];/* i_rdev */
time_t fh_post_atime; /* i_atime */ struct timespec fh_post_atime; /* i_atime */
time_t fh_post_mtime; /* i_mtime */ struct timespec fh_post_mtime; /* i_mtime */
time_t fh_post_ctime; /* i_ctime */ struct timespec fh_post_ctime; /* i_ctime */
#endif /* CONFIG_NFSD_V3 */ #endif /* CONFIG_NFSD_V3 */
} svc_fh; } svc_fh;
...@@ -263,8 +263,8 @@ fill_pre_wcc(struct svc_fh *fhp) ...@@ -263,8 +263,8 @@ fill_pre_wcc(struct svc_fh *fhp)
inode = fhp->fh_dentry->d_inode; inode = fhp->fh_dentry->d_inode;
if (!fhp->fh_pre_saved) { if (!fhp->fh_pre_saved) {
fhp->fh_pre_mtime = inode->i_mtime.tv_sec; fhp->fh_pre_mtime = inode->i_mtime;
fhp->fh_pre_ctime = inode->i_ctime.tv_sec; fhp->fh_pre_ctime = inode->i_ctime;
fhp->fh_pre_size = inode->i_size; fhp->fh_pre_size = inode->i_size;
fhp->fh_pre_saved = 1; fhp->fh_pre_saved = 1;
} }
...@@ -296,9 +296,9 @@ fill_post_wcc(struct svc_fh *fhp) ...@@ -296,9 +296,9 @@ fill_post_wcc(struct svc_fh *fhp)
} }
fhp->fh_post_rdev[0] = htonl((u32)major(inode->i_rdev)); fhp->fh_post_rdev[0] = htonl((u32)major(inode->i_rdev));
fhp->fh_post_rdev[1] = htonl((u32)minor(inode->i_rdev)); fhp->fh_post_rdev[1] = htonl((u32)minor(inode->i_rdev));
fhp->fh_post_atime = inode->i_atime.tv_sec; fhp->fh_post_atime = inode->i_atime;
fhp->fh_post_mtime = inode->i_mtime.tv_sec; fhp->fh_post_mtime = inode->i_mtime;
fhp->fh_post_ctime = inode->i_ctime.tv_sec; fhp->fh_post_ctime = inode->i_ctime;
fhp->fh_post_saved = 1; fhp->fh_post_saved = 1;
} }
#else #else
......
...@@ -331,9 +331,9 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) ...@@ -331,9 +331,9 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
cinfo->atomic = 1; cinfo->atomic = 1;
cinfo->before_size = fhp->fh_pre_size; cinfo->before_size = fhp->fh_pre_size;
cinfo->before_ctime = fhp->fh_pre_ctime; cinfo->before_ctime = fhp->fh_pre_ctime.tv_sec;
cinfo->after_size = fhp->fh_post_size; cinfo->after_size = fhp->fh_post_size;
cinfo->after_ctime = fhp->fh_post_ctime; cinfo->after_ctime = fhp->fh_post_ctime.tv_sec;
} }
int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *); int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment