Commit 3f7edeac authored by Trond Myklebust's avatar Trond Myklebust

SUNRPC: Add a transport callback to handle dequeuing of an RPC request

Add a transport level callback to allow it to handle the consequences of
dequeuing the request that was in the process of being transmitted.
For something like a TCP connection, we may need to disconnect if the
request was partially transmitted.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 0c14584c
...@@ -152,6 +152,7 @@ struct rpc_xprt_ops { ...@@ -152,6 +152,7 @@ struct rpc_xprt_ops {
int (*prepare_request)(struct rpc_rqst *req, int (*prepare_request)(struct rpc_rqst *req,
struct xdr_buf *buf); struct xdr_buf *buf);
int (*send_request)(struct rpc_rqst *req); int (*send_request)(struct rpc_rqst *req);
void (*abort_send_request)(struct rpc_rqst *req);
void (*wait_for_reply_request)(struct rpc_task *task); void (*wait_for_reply_request)(struct rpc_task *task);
void (*timer)(struct rpc_xprt *xprt, struct rpc_task *task); void (*timer)(struct rpc_xprt *xprt, struct rpc_task *task);
void (*release_request)(struct rpc_task *task); void (*release_request)(struct rpc_task *task);
......
...@@ -1398,6 +1398,12 @@ xprt_request_dequeue_transmit_locked(struct rpc_task *task) ...@@ -1398,6 +1398,12 @@ xprt_request_dequeue_transmit_locked(struct rpc_task *task)
if (!test_and_clear_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) if (!test_and_clear_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
return; return;
if (!list_empty(&req->rq_xmit)) { if (!list_empty(&req->rq_xmit)) {
struct rpc_xprt *xprt = req->rq_xprt;
if (list_is_first(&req->rq_xmit, &xprt->xmit_queue) &&
xprt->ops->abort_send_request)
xprt->ops->abort_send_request(req);
list_del(&req->rq_xmit); list_del(&req->rq_xmit);
if (!list_empty(&req->rq_xmit2)) { if (!list_empty(&req->rq_xmit2)) {
struct rpc_rqst *next = list_first_entry(&req->rq_xmit2, struct rpc_rqst *next = list_first_entry(&req->rq_xmit2,
......
...@@ -884,6 +884,17 @@ static int xs_stream_prepare_request(struct rpc_rqst *req, struct xdr_buf *buf) ...@@ -884,6 +884,17 @@ static int xs_stream_prepare_request(struct rpc_rqst *req, struct xdr_buf *buf)
return xdr_alloc_bvec(buf, rpc_task_gfp_mask()); return xdr_alloc_bvec(buf, rpc_task_gfp_mask());
} }
static void xs_stream_abort_send_request(struct rpc_rqst *req)
{
struct rpc_xprt *xprt = req->rq_xprt;
struct sock_xprt *transport =
container_of(xprt, struct sock_xprt, xprt);
if (transport->xmit.offset != 0 &&
!test_bit(XPRT_CLOSE_WAIT, &xprt->state))
xprt_force_disconnect(xprt);
}
/* /*
* Determine if the previous message in the stream was aborted before it * Determine if the previous message in the stream was aborted before it
* could complete transmission. * could complete transmission.
...@@ -3029,6 +3040,7 @@ static const struct rpc_xprt_ops xs_local_ops = { ...@@ -3029,6 +3040,7 @@ static const struct rpc_xprt_ops xs_local_ops = {
.buf_free = rpc_free, .buf_free = rpc_free,
.prepare_request = xs_stream_prepare_request, .prepare_request = xs_stream_prepare_request,
.send_request = xs_local_send_request, .send_request = xs_local_send_request,
.abort_send_request = xs_stream_abort_send_request,
.wait_for_reply_request = xprt_wait_for_reply_request_def, .wait_for_reply_request = xprt_wait_for_reply_request_def,
.close = xs_close, .close = xs_close,
.destroy = xs_destroy, .destroy = xs_destroy,
...@@ -3076,6 +3088,7 @@ static const struct rpc_xprt_ops xs_tcp_ops = { ...@@ -3076,6 +3088,7 @@ static const struct rpc_xprt_ops xs_tcp_ops = {
.buf_free = rpc_free, .buf_free = rpc_free,
.prepare_request = xs_stream_prepare_request, .prepare_request = xs_stream_prepare_request,
.send_request = xs_tcp_send_request, .send_request = xs_tcp_send_request,
.abort_send_request = xs_stream_abort_send_request,
.wait_for_reply_request = xprt_wait_for_reply_request_def, .wait_for_reply_request = xprt_wait_for_reply_request_def,
.close = xs_tcp_shutdown, .close = xs_tcp_shutdown,
.destroy = xs_destroy, .destroy = xs_destroy,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment