Commit 428a23d2 authored by J. Bruce Fields's avatar J. Bruce Fields Committed by Chuck Lever

nfsd: skip some unnecessary stats in the v4 case

In the typical case of v4 and an i_version-supporting filesystem, we can
skip a stat which is only required to fake up a change attribute from
ctime.
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 3cc55f44
...@@ -364,6 +364,11 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) ...@@ -364,6 +364,11 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
return encode_post_op_attr(rqstp, p, fhp); return encode_post_op_attr(rqstp, p, fhp);
} }
static bool fs_supports_change_attribute(struct super_block *sb)
{
return sb->s_flags & SB_I_VERSION || sb->s_export_op->fetch_iversion;
}
/* /*
* Fill in the pre_op attr for the wcc data * Fill in the pre_op attr for the wcc data
*/ */
...@@ -372,24 +377,26 @@ void fill_pre_wcc(struct svc_fh *fhp) ...@@ -372,24 +377,26 @@ void fill_pre_wcc(struct svc_fh *fhp)
struct inode *inode; struct inode *inode;
struct kstat stat; struct kstat stat;
bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE); bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
__be32 err;
if (fhp->fh_no_wcc || fhp->fh_pre_saved) if (fhp->fh_no_wcc || fhp->fh_pre_saved)
return; return;
inode = d_inode(fhp->fh_dentry); inode = d_inode(fhp->fh_dentry);
err = fh_getattr(fhp, &stat); if (fs_supports_change_attribute(inode->i_sb) || !v4) {
__be32 err = fh_getattr(fhp, &stat);
if (err) { if (err) {
/* Grab the times from inode anyway */ /* Grab the times from inode anyway */
stat.mtime = inode->i_mtime; stat.mtime = inode->i_mtime;
stat.ctime = inode->i_ctime; stat.ctime = inode->i_ctime;
stat.size = inode->i_size; stat.size = inode->i_size;
} }
if (v4)
fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
fhp->fh_pre_mtime = stat.mtime; fhp->fh_pre_mtime = stat.mtime;
fhp->fh_pre_ctime = stat.ctime; fhp->fh_pre_ctime = stat.ctime;
fhp->fh_pre_size = stat.size; fhp->fh_pre_size = stat.size;
}
if (v4)
fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
fhp->fh_pre_saved = true; fhp->fh_pre_saved = true;
} }
...@@ -400,7 +407,6 @@ void fill_post_wcc(struct svc_fh *fhp) ...@@ -400,7 +407,6 @@ void fill_post_wcc(struct svc_fh *fhp)
{ {
bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE); bool v4 = (fhp->fh_maxsize == NFS4_FHSIZE);
struct inode *inode = d_inode(fhp->fh_dentry); struct inode *inode = d_inode(fhp->fh_dentry);
__be32 err;
if (fhp->fh_no_wcc) if (fhp->fh_no_wcc)
return; return;
...@@ -408,12 +414,16 @@ void fill_post_wcc(struct svc_fh *fhp) ...@@ -408,12 +414,16 @@ void fill_post_wcc(struct svc_fh *fhp)
if (fhp->fh_post_saved) if (fhp->fh_post_saved)
printk("nfsd: inode locked twice during operation.\n"); printk("nfsd: inode locked twice during operation.\n");
err = fh_getattr(fhp, &fhp->fh_post_attr); fhp->fh_post_saved = true;
if (fs_supports_change_attribute(inode->i_sb) || !v4) {
__be32 err = fh_getattr(fhp, &fhp->fh_post_attr);
if (err) { if (err) {
fhp->fh_post_saved = false; fhp->fh_post_saved = false;
fhp->fh_post_attr.ctime = inode->i_ctime; fhp->fh_post_attr.ctime = inode->i_ctime;
} else }
fhp->fh_post_saved = true; }
if (v4) if (v4)
fhp->fh_post_change = fhp->fh_post_change =
nfsd4_change_attribute(&fhp->fh_post_attr, inode); nfsd4_change_attribute(&fhp->fh_post_attr, inode);
......
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