Commit c0aa1913 authored by Chuck Lever's avatar Chuck Lever

NFSD: Refactor nfsd_setattr()

Move code that will be retried (in a subsequent patch) into a helper
function.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
parent c035362e
...@@ -343,8 +343,61 @@ nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -343,8 +343,61 @@ nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
return nfserrno(get_write_access(inode)); return nfserrno(get_write_access(inode));
} }
/* static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap)
* Set various file attributes. After this call fhp needs an fh_put. {
int host_err;
if (iap->ia_valid & ATTR_SIZE) {
/*
* RFC5661, Section 18.30.4:
* Changing the size of a file with SETATTR indirectly
* changes the time_modify and change attributes.
*
* (and similar for the older RFCs)
*/
struct iattr size_attr = {
.ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
.ia_size = iap->ia_size,
};
if (iap->ia_size < 0)
return -EFBIG;
host_err = notify_change(&init_user_ns, dentry, &size_attr, NULL);
if (host_err)
return host_err;
iap->ia_valid &= ~ATTR_SIZE;
/*
* Avoid the additional setattr call below if the only other
* attribute that the client sends is the mtime, as we update
* it as part of the size change above.
*/
if ((iap->ia_valid & ~ATTR_MTIME) == 0)
return 0;
}
if (!iap->ia_valid)
return 0;
iap->ia_valid |= ATTR_CTIME;
return notify_change(&init_user_ns, dentry, iap, NULL);
}
/**
* nfsd_setattr - Set various file attributes.
* @rqstp: controlling RPC transaction
* @fhp: filehandle of target
* @attr: attributes to set
* @check_guard: set to 1 if guardtime is a valid timestamp
* @guardtime: do not act if ctime.tv_sec does not match this timestamp
*
* This call may adjust the contents of @attr (in particular, this
* call may change the bits in the na_iattr.ia_valid field).
*
* Returns nfs_ok on success, otherwise an NFS status code is
* returned. Caller must release @fhp by calling fh_put in either
* case.
*/ */
__be32 __be32
nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
...@@ -357,7 +410,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -357,7 +410,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
int accmode = NFSD_MAY_SATTR; int accmode = NFSD_MAY_SATTR;
umode_t ftype = 0; umode_t ftype = 0;
__be32 err; __be32 err;
int host_err = 0; int host_err;
bool get_write_count; bool get_write_count;
bool size_change = (iap->ia_valid & ATTR_SIZE); bool size_change = (iap->ia_valid & ATTR_SIZE);
...@@ -414,43 +467,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -414,43 +467,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
} }
inode_lock(inode); inode_lock(inode);
if (size_change) { host_err = __nfsd_setattr(dentry, iap);
/*
* RFC5661, Section 18.30.4:
* Changing the size of a file with SETATTR indirectly
* changes the time_modify and change attributes.
*
* (and similar for the older RFCs)
*/
struct iattr size_attr = {
.ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
.ia_size = iap->ia_size,
};
host_err = -EFBIG;
if (iap->ia_size < 0)
goto out_unlock;
host_err = notify_change(&init_user_ns, dentry, &size_attr, NULL);
if (host_err)
goto out_unlock;
iap->ia_valid &= ~ATTR_SIZE;
/*
* Avoid the additional setattr call below if the only other
* attribute that the client sends is the mtime, as we update
* it as part of the size change above.
*/
if ((iap->ia_valid & ~ATTR_MTIME) == 0)
goto out_unlock;
}
if (iap->ia_valid) {
iap->ia_valid |= ATTR_CTIME;
host_err = notify_change(&init_user_ns, dentry, iap, NULL);
}
out_unlock:
if (attr->na_seclabel && attr->na_seclabel->len) if (attr->na_seclabel && attr->na_seclabel->len)
attr->na_labelerr = security_inode_setsecctx(dentry, attr->na_labelerr = security_inode_setsecctx(dentry,
attr->na_seclabel->data, attr->na_seclabel->len); attr->na_seclabel->data, attr->na_seclabel->len);
......
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