NFS client bugfixes for Linux 5.1
Highlights include: Bugfixes: - Fix an Oops in SUNRPC back channel tracepoints - Fix a SUNRPC client regression when handling oversized replies - Fix the minimal size for SUNRPC reply buffer allocation - rpc_decode_header() must always return a non-zero value on error - Fix a typo in pnfs_update_layout() Cleanups: - Remove redundant check for the reply length in call_decode() -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJcjT+5AAoJEA4mA3inWBJcp0wQAJzO0TXu81pDPuq7qGxjtgc6 jKyvxA180OuVb0dkMDhgLURnHRvrn89yHWt6X4TYHkKMIdhcKAaO+yTqZeeyr4cx N4PC6kSXD2b3+X2F6qbYF9VKBI3nv9aCEpevWTnL+xQNxLqj96mNhy5w3l6Jlvyf gk++LcxJs5YuhnuQ76qDIfH5kiVb1qlmd95nYvf0vYz0w4AuwNcnmHooSWJo66Gi UF65f//8xtrV1XRCtEBTIaeb841RvWFAPW0hCWGNfojRpqFYFgqE1FzlfL+my3Rx abp75MhDvB4bVLyRtlMLfS7Cybz4t/J7YKRxsYeZJQ/PCG3kO1g1sbqJXIEsT+c9 bOhYqTvoUAmbWckdw9f4yI5LkLCHAExfDynJOIbSClacZVyG2DANVwXPr/76hNNm HSUdmw/LwaKjea99gkbPESlHIzmNScDoydb7vzhcXTm/uufGvKy59SeboI/J5c5U HwY/dTg9dLofE54IibBBsyzxmGp1JBOy0/0k0o2FSTPHHeZBVvdjiNawpympDck4 c+TR4Pvw4LBBVEB/EEcWbpa28k/irlh7PeOiCWqopUR+IOWEY12dMCphswGh11vj +H6N6ALtL2AKeQIDkoASdIuufveeVlwzosI+JheO7wxo3b1l+BI3x5xght+2aKeE pi+C3nSslqlJ3PUO++wa =cNDi -----END PGP SIGNATURE----- Merge tag 'nfs-for-5.1-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs Pull NFS client bugfixes from Trond Myklebust: "Highlights include: Bugfixes: - Fix an Oops in SUNRPC back channel tracepoints - Fix a SUNRPC client regression when handling oversized replies - Fix the minimal size for SUNRPC reply buffer allocation - rpc_decode_header() must always return a non-zero value on error - Fix a typo in pnfs_update_layout() Cleanup: - Remove redundant check for the reply length in call_decode()" * tag 'nfs-for-5.1-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: SUNRPC: Remove redundant check for the reply length in call_decode() SUNRPC: Handle the SYSTEM_ERR rpc error SUNRPC: rpc_decode_header() must always return a non-zero value on error SUNRPC: Use the ENOTCONN error on socket disconnect SUNRPC: Fix the minimal size for reply buffer allocation SUNRPC: Fix a client regression when handling oversized replies pNFS: Fix a typo in pnfs_update_layout fix null pointer deref in tracepoints in back channel
This commit is contained in:
commit
465c209db8
|
@ -1889,7 +1889,7 @@ lookup_again:
|
|||
atomic_read(&lo->plh_outstanding) != 0) {
|
||||
spin_unlock(&ino->i_lock);
|
||||
lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding,
|
||||
atomic_read(&lo->plh_outstanding)));
|
||||
!atomic_read(&lo->plh_outstanding)));
|
||||
if (IS_ERR(lseg) || !list_empty(&lo->plh_segs))
|
||||
goto out_put_layout_hdr;
|
||||
pnfs_put_layout_hdr(lo);
|
||||
|
|
|
@ -712,7 +712,8 @@ TRACE_EVENT(xprt_transmit,
|
|||
|
||||
TP_fast_assign(
|
||||
__entry->task_id = rqst->rq_task->tk_pid;
|
||||
__entry->client_id = rqst->rq_task->tk_client->cl_clid;
|
||||
__entry->client_id = rqst->rq_task->tk_client ?
|
||||
rqst->rq_task->tk_client->cl_clid : -1;
|
||||
__entry->xid = be32_to_cpu(rqst->rq_xid);
|
||||
__entry->seqno = rqst->rq_seqno;
|
||||
__entry->status = status;
|
||||
|
@ -742,7 +743,8 @@ TRACE_EVENT(xprt_enq_xmit,
|
|||
|
||||
TP_fast_assign(
|
||||
__entry->task_id = task->tk_pid;
|
||||
__entry->client_id = task->tk_client->cl_clid;
|
||||
__entry->client_id = task->tk_client ?
|
||||
task->tk_client->cl_clid : -1;
|
||||
__entry->xid = be32_to_cpu(task->tk_rqstp->rq_xid);
|
||||
__entry->seqno = task->tk_rqstp->rq_seqno;
|
||||
__entry->stage = stage;
|
||||
|
|
|
@ -1730,7 +1730,12 @@ call_allocate(struct rpc_task *task)
|
|||
req->rq_callsize = RPC_CALLHDRSIZE + (auth->au_cslack << 1) +
|
||||
proc->p_arglen;
|
||||
req->rq_callsize <<= 2;
|
||||
req->rq_rcvsize = RPC_REPHDRSIZE + auth->au_rslack + proc->p_replen;
|
||||
/*
|
||||
* Note: the reply buffer must at minimum allocate enough space
|
||||
* for the 'struct accepted_reply' from RFC5531.
|
||||
*/
|
||||
req->rq_rcvsize = RPC_REPHDRSIZE + auth->au_rslack + \
|
||||
max_t(size_t, proc->p_replen, 2);
|
||||
req->rq_rcvsize <<= 2;
|
||||
|
||||
status = xprt->ops->buf_alloc(task);
|
||||
|
@ -2387,9 +2392,6 @@ call_decode(struct rpc_task *task)
|
|||
WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf,
|
||||
sizeof(req->rq_rcv_buf)) != 0);
|
||||
|
||||
if (req->rq_rcv_buf.len < 12)
|
||||
goto out_retry;
|
||||
|
||||
xdr_init_decode(&xdr, &req->rq_rcv_buf,
|
||||
req->rq_rcv_buf.head[0].iov_base, req);
|
||||
switch (rpc_decode_header(task, &xdr)) {
|
||||
|
@ -2400,7 +2402,6 @@ call_decode(struct rpc_task *task)
|
|||
task->tk_pid, __func__, task->tk_status);
|
||||
return;
|
||||
case -EAGAIN:
|
||||
out_retry:
|
||||
task->tk_status = 0;
|
||||
/* Note: rpc_decode_header() may have freed the RPC slot */
|
||||
if (task->tk_rqstp == req) {
|
||||
|
@ -2449,7 +2450,7 @@ static noinline int
|
|||
rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
|
||||
{
|
||||
struct rpc_clnt *clnt = task->tk_client;
|
||||
int error = -EACCES;
|
||||
int error;
|
||||
__be32 *p;
|
||||
|
||||
/* RFC-1014 says that the representation of XDR data must be a
|
||||
|
@ -2458,7 +2459,7 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
|
|||
* undefined results
|
||||
*/
|
||||
if (task->tk_rqstp->rq_rcv_buf.len & 3)
|
||||
goto out_badlen;
|
||||
goto out_unparsable;
|
||||
|
||||
p = xdr_inline_decode(xdr, 3 * sizeof(*p));
|
||||
if (!p)
|
||||
|
@ -2492,10 +2493,12 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
|
|||
error = -EOPNOTSUPP;
|
||||
goto out_err;
|
||||
case rpc_garbage_args:
|
||||
case rpc_system_err:
|
||||
trace_rpc__garbage_args(task);
|
||||
error = -EIO;
|
||||
break;
|
||||
default:
|
||||
trace_rpc__unparsable(task);
|
||||
goto out_unparsable;
|
||||
}
|
||||
|
||||
out_garbage:
|
||||
|
@ -2509,11 +2512,6 @@ out_err:
|
|||
rpc_exit(task, error);
|
||||
return error;
|
||||
|
||||
out_badlen:
|
||||
trace_rpc__unparsable(task);
|
||||
error = -EIO;
|
||||
goto out_err;
|
||||
|
||||
out_unparsable:
|
||||
trace_rpc__unparsable(task);
|
||||
error = -EIO;
|
||||
|
@ -2524,6 +2522,7 @@ out_verifier:
|
|||
goto out_garbage;
|
||||
|
||||
out_msg_denied:
|
||||
error = -EACCES;
|
||||
p = xdr_inline_decode(xdr, sizeof(*p));
|
||||
if (!p)
|
||||
goto out_unparsable;
|
||||
|
@ -2535,9 +2534,7 @@ out_msg_denied:
|
|||
error = -EPROTONOSUPPORT;
|
||||
goto out_err;
|
||||
default:
|
||||
trace_rpc__unparsable(task);
|
||||
error = -EIO;
|
||||
goto out_err;
|
||||
goto out_unparsable;
|
||||
}
|
||||
|
||||
p = xdr_inline_decode(xdr, sizeof(*p));
|
||||
|
@ -2572,8 +2569,7 @@ out_msg_denied:
|
|||
task->tk_xprt->servername);
|
||||
break;
|
||||
default:
|
||||
trace_rpc__unparsable(task);
|
||||
error = -EIO;
|
||||
goto out_unparsable;
|
||||
}
|
||||
goto out_err;
|
||||
}
|
||||
|
|
|
@ -664,7 +664,7 @@ void xprt_disconnect_done(struct rpc_xprt *xprt)
|
|||
spin_lock_bh(&xprt->transport_lock);
|
||||
xprt_clear_connected(xprt);
|
||||
xprt_clear_write_space_locked(xprt);
|
||||
xprt_wake_pending_tasks(xprt, -EAGAIN);
|
||||
xprt_wake_pending_tasks(xprt, -ENOTCONN);
|
||||
spin_unlock_bh(&xprt->transport_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xprt_disconnect_done);
|
||||
|
|
|
@ -453,7 +453,7 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr *msg, int flags,
|
|||
goto out;
|
||||
if (ret != want)
|
||||
goto out;
|
||||
} else
|
||||
} else if (offset < seek_init)
|
||||
offset = seek_init;
|
||||
ret = -EMSGSIZE;
|
||||
out:
|
||||
|
|
Loading…
Reference in New Issue