NFSD: Refactor nfsd_setattr()
Move code that will be retried (in a subsequent patch) into a helper function. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org>
This commit is contained in:
parent
c035362eb9
commit
c0aa1913db
@ -343,8 +343,61 @@ nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
return nfserrno(get_write_access(inode));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set various file attributes. After this call fhp needs an fh_put.
|
||||
static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap)
|
||||
{
|
||||
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
|
||||
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;
|
||||
umode_t ftype = 0;
|
||||
__be32 err;
|
||||
int host_err = 0;
|
||||
int host_err;
|
||||
bool get_write_count;
|
||||
bool size_change = (iap->ia_valid & ATTR_SIZE);
|
||||
|
||||
@ -414,43 +467,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||
}
|
||||
|
||||
inode_lock(inode);
|
||||
if (size_change) {
|
||||
/*
|
||||
* 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:
|
||||
host_err = __nfsd_setattr(dentry, iap);
|
||||
if (attr->na_seclabel && attr->na_seclabel->len)
|
||||
attr->na_labelerr = security_inode_setsecctx(dentry,
|
||||
attr->na_seclabel->data, attr->na_seclabel->len);
|
||||
|
Loading…
x
Reference in New Issue
Block a user