Merge tag 'nfsd-4.21' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "Thanks to Vasily Averin for fixing a use-after-free in the containerized NFSv4.2 client, and cleaning up some convoluted backchannel server code in the process. Otherwise, miscellaneous smaller bugfixes and cleanup" * tag 'nfsd-4.21' of git://linux-nfs.org/~bfields/linux: (25 commits) nfs: fixed broken compilation in nfs_callback_up_net() nfs: minor typo in nfs4_callback_up_net() sunrpc: fix debug message in svc_create_xprt() sunrpc: make visible processing error in bc_svc_process() sunrpc: remove unused xpo_prep_reply_hdr callback sunrpc: remove svc_rdma_bc_class sunrpc: remove svc_tcp_bc_class sunrpc: remove unused bc_up operation from rpc_xprt_ops sunrpc: replace svc_serv->sv_bc_xprt by boolean flag sunrpc: use-after-free in svc_process_common() sunrpc: use SVC_NET() in svcauth_gss_* functions nfsd: drop useless LIST_HEAD lockd: Show pid of lockd for remote locks NFSD remove OP_CACHEME from 4.2 op_flags nfsd: Return EPERM, not EACCES, in some SETATTR cases sunrpc: fix cache_head leak due to queued request nfsd: clean up indentation, increase indentation in switch statement svcrdma: Optimize the logic that selects the R_key to invalidate nfsd: fix a warning in __cld_pipe_upcall() nfsd4: fix crash on writing v4_end_grace before nfsd startup ...
This commit is contained in:
@@ -656,7 +656,6 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
|
||||
struct nfsd_net *nn;
|
||||
ktime_t now, cutoff;
|
||||
const struct nfsd4_layout_ops *ops;
|
||||
LIST_HEAD(reaplist);
|
||||
|
||||
|
||||
switch (task->tk_status) {
|
||||
|
@@ -863,8 +863,7 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
struct nfsd4_rename *rename = &u->rename;
|
||||
__be32 status;
|
||||
|
||||
if (opens_in_grace(SVC_NET(rqstp)) &&
|
||||
!(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK))
|
||||
if (opens_in_grace(SVC_NET(rqstp)))
|
||||
return nfserr_grace;
|
||||
status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
|
||||
rename->rn_snamelen, &cstate->current_fh,
|
||||
@@ -1016,8 +1015,6 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
|
||||
nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
|
||||
&write->wr_head, write->wr_buflen);
|
||||
if (!nvecs)
|
||||
return nfserr_io;
|
||||
WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
|
||||
|
||||
status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp,
|
||||
@@ -1348,7 +1345,7 @@ static __be32
|
||||
nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
struct nfsd4_fallocate *fallocate, int flags)
|
||||
{
|
||||
__be32 status = nfserr_notsupp;
|
||||
__be32 status;
|
||||
struct file *file;
|
||||
|
||||
status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
|
||||
@@ -2682,25 +2679,25 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
||||
/* NFSv4.2 operations */
|
||||
[OP_ALLOCATE] = {
|
||||
.op_func = nfsd4_allocate,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_flags = OP_MODIFIES_SOMETHING,
|
||||
.op_name = "OP_ALLOCATE",
|
||||
.op_rsize_bop = nfsd4_only_status_rsize,
|
||||
},
|
||||
[OP_DEALLOCATE] = {
|
||||
.op_func = nfsd4_deallocate,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_flags = OP_MODIFIES_SOMETHING,
|
||||
.op_name = "OP_DEALLOCATE",
|
||||
.op_rsize_bop = nfsd4_only_status_rsize,
|
||||
},
|
||||
[OP_CLONE] = {
|
||||
.op_func = nfsd4_clone,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_flags = OP_MODIFIES_SOMETHING,
|
||||
.op_name = "OP_CLONE",
|
||||
.op_rsize_bop = nfsd4_only_status_rsize,
|
||||
},
|
||||
[OP_COPY] = {
|
||||
.op_func = nfsd4_copy,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_flags = OP_MODIFIES_SOMETHING,
|
||||
.op_name = "OP_COPY",
|
||||
.op_rsize_bop = nfsd4_copy_rsize,
|
||||
},
|
||||
|
@@ -662,7 +662,7 @@ struct cld_net {
|
||||
struct cld_upcall {
|
||||
struct list_head cu_list;
|
||||
struct cld_net *cu_net;
|
||||
struct task_struct *cu_task;
|
||||
struct completion cu_done;
|
||||
struct cld_msg cu_msg;
|
||||
};
|
||||
|
||||
@@ -671,23 +671,18 @@ __cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
|
||||
{
|
||||
int ret;
|
||||
struct rpc_pipe_msg msg;
|
||||
struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_msg);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.data = cmsg;
|
||||
msg.len = sizeof(*cmsg);
|
||||
|
||||
/*
|
||||
* Set task state before we queue the upcall. That prevents
|
||||
* wake_up_process in the downcall from racing with schedule.
|
||||
*/
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
ret = rpc_queue_upcall(pipe, &msg);
|
||||
if (ret < 0) {
|
||||
set_current_state(TASK_RUNNING);
|
||||
goto out;
|
||||
}
|
||||
|
||||
schedule();
|
||||
wait_for_completion(&cup->cu_done);
|
||||
|
||||
if (msg.errno < 0)
|
||||
ret = msg.errno;
|
||||
@@ -754,7 +749,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
|
||||
if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
|
||||
return -EFAULT;
|
||||
|
||||
wake_up_process(cup->cu_task);
|
||||
complete(&cup->cu_done);
|
||||
return mlen;
|
||||
}
|
||||
|
||||
@@ -769,7 +764,7 @@ cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
|
||||
if (msg->errno >= 0)
|
||||
return;
|
||||
|
||||
wake_up_process(cup->cu_task);
|
||||
complete(&cup->cu_done);
|
||||
}
|
||||
|
||||
static const struct rpc_pipe_ops cld_upcall_ops = {
|
||||
@@ -900,7 +895,7 @@ restart_search:
|
||||
goto restart_search;
|
||||
}
|
||||
}
|
||||
new->cu_task = current;
|
||||
init_completion(&new->cu_done);
|
||||
new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
|
||||
put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
|
||||
new->cu_net = cn;
|
||||
|
@@ -5112,7 +5112,7 @@ nfs4_find_file(struct nfs4_stid *s, int flags)
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfs4_check_olstateid(struct svc_fh *fhp, struct nfs4_ol_stateid *ols, int flags)
|
||||
nfs4_check_olstateid(struct nfs4_ol_stateid *ols, int flags)
|
||||
{
|
||||
__be32 status;
|
||||
|
||||
@@ -5195,7 +5195,7 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
|
||||
break;
|
||||
case NFS4_OPEN_STID:
|
||||
case NFS4_LOCK_STID:
|
||||
status = nfs4_check_olstateid(fhp, openlockstateid(s), flags);
|
||||
status = nfs4_check_olstateid(openlockstateid(s), flags);
|
||||
break;
|
||||
default:
|
||||
status = nfserr_bad_stateid;
|
||||
@@ -6230,15 +6230,15 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
case NFS4_READ_LT:
|
||||
case NFS4_READW_LT:
|
||||
file_lock->fl_type = F_RDLCK;
|
||||
break;
|
||||
break;
|
||||
case NFS4_WRITE_LT:
|
||||
case NFS4_WRITEW_LT:
|
||||
file_lock->fl_type = F_WRLCK;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
dprintk("NFSD: nfs4_lockt: bad lock type!\n");
|
||||
status = nfserr_inval;
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
lo = find_lockowner_str(cstate->clp, &lockt->lt_owner);
|
||||
|
@@ -1126,6 +1126,8 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
|
||||
case 'Y':
|
||||
case 'y':
|
||||
case '1':
|
||||
if (nn->nfsd_serv)
|
||||
return -EBUSY;
|
||||
nfsd4_end_grace(nn);
|
||||
break;
|
||||
default:
|
||||
|
@@ -396,10 +396,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
||||
bool get_write_count;
|
||||
bool size_change = (iap->ia_valid & ATTR_SIZE);
|
||||
|
||||
if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
|
||||
if (iap->ia_valid & ATTR_SIZE) {
|
||||
accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
|
||||
if (iap->ia_valid & ATTR_SIZE)
|
||||
ftype = S_IFREG;
|
||||
}
|
||||
|
||||
/*
|
||||
* If utimes(2) and friends are called with times not NULL, we should
|
||||
* not set NFSD_MAY_WRITE bit. Otherwise fh_verify->nfsd_permission
|
||||
* will return EACCESS, when the caller's effective UID does not match
|
||||
* the owner of the file, and the caller is not privileged. In this
|
||||
* situation, we should return EPERM(notify_change will return this).
|
||||
*/
|
||||
if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME)) {
|
||||
accmode |= NFSD_MAY_OWNER_OVERRIDE;
|
||||
if (!(iap->ia_valid & (ATTR_ATIME_SET | ATTR_MTIME_SET)))
|
||||
accmode |= NFSD_MAY_WRITE;
|
||||
}
|
||||
|
||||
/* Callers that do fh_verify should do the fh_want_write: */
|
||||
get_write_count = !fhp->fh_dentry;
|
||||
|
Reference in New Issue
Block a user