Skip to content

Commit 72691a2

Browse files
author
Trond Myklebust
committed
SUNRPC: Don't reuse bvec on retransmission of the request
If a request is re-encoded and then retransmitted, we need to make sure that we also re-encode the bvec, in case the page lists have changed. Fixes: ff053db ("SUNRPC: Move the call to xprt_send_pagedata() out of xprt_sock_sendmsg()") Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 6622e3a commit 72691a2

File tree

4 files changed

+22
-21
lines changed

4 files changed

+22
-21
lines changed

include/linux/sunrpc/xprt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ struct rpc_xprt_ops {
144144
unsigned short (*get_srcport)(struct rpc_xprt *xprt);
145145
int (*buf_alloc)(struct rpc_task *task);
146146
void (*buf_free)(struct rpc_task *task);
147-
int (*prepare_request)(struct rpc_rqst *req);
147+
int (*prepare_request)(struct rpc_rqst *req,
148+
struct xdr_buf *buf);
148149
int (*send_request)(struct rpc_rqst *req);
149150
void (*wait_for_reply_request)(struct rpc_task *task);
150151
void (*timer)(struct rpc_xprt *xprt, struct rpc_task *task);

net/sunrpc/clnt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,6 @@ rpc_xdr_encode(struct rpc_task *task)
18701870
req->rq_snd_buf.head[0].iov_len = 0;
18711871
xdr_init_encode(&xdr, &req->rq_snd_buf,
18721872
req->rq_snd_buf.head[0].iov_base, req);
1873-
xdr_free_bvec(&req->rq_snd_buf);
18741873
if (rpc_encode_header(task, &xdr))
18751874
return;
18761875

net/sunrpc/xprt.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net);
7373
static __be32 xprt_alloc_xid(struct rpc_xprt *xprt);
7474
static void xprt_destroy(struct rpc_xprt *xprt);
7575
static void xprt_request_init(struct rpc_task *task);
76-
static int xprt_request_prepare(struct rpc_rqst *req);
76+
static int xprt_request_prepare(struct rpc_rqst *req, struct xdr_buf *buf);
7777

7878
static DEFINE_SPINLOCK(xprt_list_lock);
7979
static LIST_HEAD(xprt_list);
@@ -1149,7 +1149,7 @@ xprt_request_enqueue_receive(struct rpc_task *task)
11491149
if (!xprt_request_need_enqueue_receive(task, req))
11501150
return 0;
11511151

1152-
ret = xprt_request_prepare(task->tk_rqstp);
1152+
ret = xprt_request_prepare(task->tk_rqstp, &req->rq_rcv_buf);
11531153
if (ret)
11541154
return ret;
11551155
spin_lock(&xprt->queue_lock);
@@ -1179,8 +1179,11 @@ xprt_request_dequeue_receive_locked(struct rpc_task *task)
11791179
{
11801180
struct rpc_rqst *req = task->tk_rqstp;
11811181

1182-
if (test_and_clear_bit(RPC_TASK_NEED_RECV, &task->tk_runstate))
1182+
if (test_and_clear_bit(RPC_TASK_NEED_RECV, &task->tk_runstate)) {
11831183
xprt_request_rb_remove(req->rq_xprt, req);
1184+
xdr_free_bvec(&req->rq_rcv_buf);
1185+
req->rq_private_buf.bvec = NULL;
1186+
}
11841187
}
11851188

11861189
/**
@@ -1336,8 +1339,14 @@ xprt_request_enqueue_transmit(struct rpc_task *task)
13361339
{
13371340
struct rpc_rqst *pos, *req = task->tk_rqstp;
13381341
struct rpc_xprt *xprt = req->rq_xprt;
1342+
int ret;
13391343

13401344
if (xprt_request_need_enqueue_transmit(task, req)) {
1345+
ret = xprt_request_prepare(task->tk_rqstp, &req->rq_snd_buf);
1346+
if (ret) {
1347+
task->tk_status = ret;
1348+
return;
1349+
}
13411350
req->rq_bytes_sent = 0;
13421351
spin_lock(&xprt->queue_lock);
13431352
/*
@@ -1397,6 +1406,7 @@ xprt_request_dequeue_transmit_locked(struct rpc_task *task)
13971406
} else
13981407
list_del(&req->rq_xmit2);
13991408
atomic_long_dec(&req->rq_xprt->xmit_queuelen);
1409+
xdr_free_bvec(&req->rq_snd_buf);
14001410
}
14011411

14021412
/**
@@ -1433,34 +1443,35 @@ xprt_request_dequeue_xprt(struct rpc_task *task)
14331443
test_bit(RPC_TASK_NEED_RECV, &task->tk_runstate) ||
14341444
xprt_is_pinned_rqst(req)) {
14351445
spin_lock(&xprt->queue_lock);
1436-
xprt_request_dequeue_transmit_locked(task);
1437-
xprt_request_dequeue_receive_locked(task);
14381446
while (xprt_is_pinned_rqst(req)) {
14391447
set_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate);
14401448
spin_unlock(&xprt->queue_lock);
14411449
xprt_wait_on_pinned_rqst(req);
14421450
spin_lock(&xprt->queue_lock);
14431451
clear_bit(RPC_TASK_MSG_PIN_WAIT, &task->tk_runstate);
14441452
}
1453+
xprt_request_dequeue_transmit_locked(task);
1454+
xprt_request_dequeue_receive_locked(task);
14451455
spin_unlock(&xprt->queue_lock);
14461456
}
14471457
}
14481458

14491459
/**
14501460
* xprt_request_prepare - prepare an encoded request for transport
14511461
* @req: pointer to rpc_rqst
1462+
* @buf: pointer to send/rcv xdr_buf
14521463
*
14531464
* Calls into the transport layer to do whatever is needed to prepare
14541465
* the request for transmission or receive.
14551466
* Returns error, or zero.
14561467
*/
14571468
static int
1458-
xprt_request_prepare(struct rpc_rqst *req)
1469+
xprt_request_prepare(struct rpc_rqst *req, struct xdr_buf *buf)
14591470
{
14601471
struct rpc_xprt *xprt = req->rq_xprt;
14611472

14621473
if (xprt->ops->prepare_request)
1463-
return xprt->ops->prepare_request(req);
1474+
return xprt->ops->prepare_request(req, buf);
14641475
return 0;
14651476
}
14661477

@@ -1961,8 +1972,6 @@ void xprt_release(struct rpc_task *task)
19611972
spin_unlock(&xprt->transport_lock);
19621973
if (req->rq_buffer)
19631974
xprt->ops->buf_free(task);
1964-
xdr_free_bvec(&req->rq_rcv_buf);
1965-
xdr_free_bvec(&req->rq_snd_buf);
19661975
if (req->rq_cred != NULL)
19671976
put_rpccred(req->rq_cred);
19681977
if (req->rq_release_snd_buf)

net/sunrpc/xprtsock.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -822,17 +822,9 @@ static int xs_stream_nospace(struct rpc_rqst *req, bool vm_wait)
822822
return ret;
823823
}
824824

825-
static int
826-
xs_stream_prepare_request(struct rpc_rqst *req)
825+
static int xs_stream_prepare_request(struct rpc_rqst *req, struct xdr_buf *buf)
827826
{
828-
gfp_t gfp = rpc_task_gfp_mask();
829-
int ret;
830-
831-
ret = xdr_alloc_bvec(&req->rq_snd_buf, gfp);
832-
if (ret < 0)
833-
return ret;
834-
xdr_free_bvec(&req->rq_rcv_buf);
835-
return xdr_alloc_bvec(&req->rq_rcv_buf, gfp);
827+
return xdr_alloc_bvec(buf, rpc_task_gfp_mask());
836828
}
837829

838830
/*

0 commit comments

Comments
 (0)