Skip to content

Commit fc89182

Browse files
committed
Merge tag 'nfs-for-4.4-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfix from Trond Myklebust: "SUNRPC: Fix a NFSv4.1 callback channel regression" * tag 'nfs-for-4.4-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: SUNRPC: Fix callback channel
2 parents dec9cbf + 756b9b3 commit fc89182

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

fs/nfs/callback_xdr.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ static __be32 *read_buf(struct xdr_stream *xdr, int nbytes)
7878

7979
p = xdr_inline_decode(xdr, nbytes);
8080
if (unlikely(p == NULL))
81-
printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed "
82-
"or truncated request.\n");
81+
printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n");
8382
return p;
8483
}
8584

@@ -890,7 +889,6 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
890889
struct cb_compound_hdr_arg hdr_arg = { 0 };
891890
struct cb_compound_hdr_res hdr_res = { NULL };
892891
struct xdr_stream xdr_in, xdr_out;
893-
struct xdr_buf *rq_arg = &rqstp->rq_arg;
894892
__be32 *p, status;
895893
struct cb_process_state cps = {
896894
.drc_status = 0,
@@ -902,8 +900,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
902900

903901
dprintk("%s: start\n", __func__);
904902

905-
rq_arg->len = rq_arg->head[0].iov_len + rq_arg->page_len;
906-
xdr_init_decode(&xdr_in, rq_arg, rq_arg->head[0].iov_base);
903+
xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
907904

908905
p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
909906
xdr_init_encode(&xdr_out, &rqstp->rq_res, p);

net/sunrpc/backchannel_rqst.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -353,20 +353,12 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
353353
{
354354
struct rpc_xprt *xprt = req->rq_xprt;
355355
struct svc_serv *bc_serv = xprt->bc_serv;
356-
struct xdr_buf *rq_rcv_buf = &req->rq_rcv_buf;
357356

358357
spin_lock(&xprt->bc_pa_lock);
359358
list_del(&req->rq_bc_pa_list);
360359
xprt_dec_alloc_count(xprt, 1);
361360
spin_unlock(&xprt->bc_pa_lock);
362361

363-
if (copied <= rq_rcv_buf->head[0].iov_len) {
364-
rq_rcv_buf->head[0].iov_len = copied;
365-
rq_rcv_buf->page_len = 0;
366-
} else {
367-
rq_rcv_buf->page_len = copied - rq_rcv_buf->head[0].iov_len;
368-
}
369-
370362
req->rq_private_buf.len = copied;
371363
set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
372364

net/sunrpc/svc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,19 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
13631363
memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
13641364
memcpy(&rqstp->rq_arg, &req->rq_rcv_buf, sizeof(rqstp->rq_arg));
13651365
memcpy(&rqstp->rq_res, &req->rq_snd_buf, sizeof(rqstp->rq_res));
1366+
1367+
/* Adjust the argument buffer length */
13661368
rqstp->rq_arg.len = req->rq_private_buf.len;
1369+
if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
1370+
rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
1371+
rqstp->rq_arg.page_len = 0;
1372+
} else if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len +
1373+
rqstp->rq_arg.page_len)
1374+
rqstp->rq_arg.page_len = rqstp->rq_arg.len -
1375+
rqstp->rq_arg.head[0].iov_len;
1376+
else
1377+
rqstp->rq_arg.len = rqstp->rq_arg.head[0].iov_len +
1378+
rqstp->rq_arg.page_len;
13671379

13681380
/* reset result send buffer "put" position */
13691381
resv->iov_len = 0;

0 commit comments

Comments
 (0)