SUNRPC: Fix up the back channel transmit
Fix up the back channel code to recognise that it has already been transmitted, so does not need to be called again. Also ensure that we set req->rq_task. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
762e4e67b3
commit
902c58872e
|
@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifdef CONFIG_SUNRPC_BACKCHANNEL
|
#ifdef CONFIG_SUNRPC_BACKCHANNEL
|
||||||
struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid);
|
struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid);
|
||||||
void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied);
|
void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied);
|
||||||
|
void xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task);
|
||||||
void xprt_free_bc_request(struct rpc_rqst *req);
|
void xprt_free_bc_request(struct rpc_rqst *req);
|
||||||
int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
|
int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
|
||||||
void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
|
void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
|
||||||
|
|
|
@ -1138,7 +1138,6 @@ EXPORT_SYMBOL_GPL(rpc_call_async);
|
||||||
struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req)
|
struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req)
|
||||||
{
|
{
|
||||||
struct rpc_task *task;
|
struct rpc_task *task;
|
||||||
struct xdr_buf *xbufp = &req->rq_snd_buf;
|
|
||||||
struct rpc_task_setup task_setup_data = {
|
struct rpc_task_setup task_setup_data = {
|
||||||
.callback_ops = &rpc_default_ops,
|
.callback_ops = &rpc_default_ops,
|
||||||
.flags = RPC_TASK_SOFTCONN |
|
.flags = RPC_TASK_SOFTCONN |
|
||||||
|
@ -1150,14 +1149,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req)
|
||||||
* Create an rpc_task to send the data
|
* Create an rpc_task to send the data
|
||||||
*/
|
*/
|
||||||
task = rpc_new_task(&task_setup_data);
|
task = rpc_new_task(&task_setup_data);
|
||||||
task->tk_rqstp = req;
|
xprt_init_bc_request(req, task);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the xdr_buf length.
|
|
||||||
* This also indicates that the buffer is XDR encoded already.
|
|
||||||
*/
|
|
||||||
xbufp->len = xbufp->head[0].iov_len + xbufp->page_len +
|
|
||||||
xbufp->tail[0].iov_len;
|
|
||||||
|
|
||||||
task->tk_action = call_bc_transmit;
|
task->tk_action = call_bc_transmit;
|
||||||
atomic_inc(&task->tk_count);
|
atomic_inc(&task->tk_count);
|
||||||
|
@ -2064,6 +2056,8 @@ call_bc_transmit(struct rpc_task *task)
|
||||||
|
|
||||||
if (rpc_task_need_encode(task))
|
if (rpc_task_need_encode(task))
|
||||||
xprt_request_enqueue_transmit(task);
|
xprt_request_enqueue_transmit(task);
|
||||||
|
if (!test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate))
|
||||||
|
goto out_wakeup;
|
||||||
|
|
||||||
if (!xprt_prepare_transmit(task))
|
if (!xprt_prepare_transmit(task))
|
||||||
goto out_retry;
|
goto out_retry;
|
||||||
|
@ -2073,13 +2067,11 @@ call_bc_transmit(struct rpc_task *task)
|
||||||
"error: %d\n", task->tk_status);
|
"error: %d\n", task->tk_status);
|
||||||
goto out_done;
|
goto out_done;
|
||||||
}
|
}
|
||||||
if (req->rq_connect_cookie != req->rq_xprt->connect_cookie)
|
|
||||||
req->rq_bytes_sent = 0;
|
|
||||||
|
|
||||||
xprt_transmit(task);
|
xprt_transmit(task);
|
||||||
|
|
||||||
if (task->tk_status == -EAGAIN)
|
if (task->tk_status == -EAGAIN)
|
||||||
goto out_nospace;
|
goto out_retry;
|
||||||
|
|
||||||
xprt_end_transmit(task);
|
xprt_end_transmit(task);
|
||||||
dprint_status(task);
|
dprint_status(task);
|
||||||
|
@ -2119,12 +2111,11 @@ call_bc_transmit(struct rpc_task *task)
|
||||||
"error: %d\n", task->tk_status);
|
"error: %d\n", task->tk_status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out_wakeup:
|
||||||
rpc_wake_up_queued_task(&req->rq_xprt->pending, task);
|
rpc_wake_up_queued_task(&req->rq_xprt->pending, task);
|
||||||
out_done:
|
out_done:
|
||||||
task->tk_action = rpc_exit_task;
|
task->tk_action = rpc_exit_task;
|
||||||
return;
|
return;
|
||||||
out_nospace:
|
|
||||||
req->rq_connect_cookie = req->rq_xprt->connect_cookie;
|
|
||||||
out_retry:
|
out_retry:
|
||||||
task->tk_status = 0;
|
task->tk_status = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1390,6 +1390,12 @@ void xprt_free(struct rpc_xprt *xprt)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xprt_free);
|
EXPORT_SYMBOL_GPL(xprt_free);
|
||||||
|
|
||||||
|
static void
|
||||||
|
xprt_init_connect_cookie(struct rpc_rqst *req, struct rpc_xprt *xprt)
|
||||||
|
{
|
||||||
|
req->rq_connect_cookie = xprt_connect_cookie(xprt) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
static __be32
|
static __be32
|
||||||
xprt_alloc_xid(struct rpc_xprt *xprt)
|
xprt_alloc_xid(struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
|
@ -1418,7 +1424,7 @@ xprt_request_init(struct rpc_task *task)
|
||||||
req->rq_xprt = xprt;
|
req->rq_xprt = xprt;
|
||||||
req->rq_buffer = NULL;
|
req->rq_buffer = NULL;
|
||||||
req->rq_xid = xprt_alloc_xid(xprt);
|
req->rq_xid = xprt_alloc_xid(xprt);
|
||||||
req->rq_connect_cookie = xprt_connect_cookie(xprt) - 1;
|
xprt_init_connect_cookie(req, xprt);
|
||||||
req->rq_bytes_sent = 0;
|
req->rq_bytes_sent = 0;
|
||||||
req->rq_snd_buf.len = 0;
|
req->rq_snd_buf.len = 0;
|
||||||
req->rq_snd_buf.buflen = 0;
|
req->rq_snd_buf.buflen = 0;
|
||||||
|
@ -1552,6 +1558,25 @@ void xprt_release(struct rpc_task *task)
|
||||||
xprt_free_bc_request(req);
|
xprt_free_bc_request(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUNRPC_BACKCHANNEL
|
||||||
|
void
|
||||||
|
xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task)
|
||||||
|
{
|
||||||
|
struct xdr_buf *xbufp = &req->rq_snd_buf;
|
||||||
|
|
||||||
|
task->tk_rqstp = req;
|
||||||
|
req->rq_task = task;
|
||||||
|
xprt_init_connect_cookie(req, req->rq_xprt);
|
||||||
|
/*
|
||||||
|
* Set up the xdr_buf length.
|
||||||
|
* This also indicates that the buffer is XDR encoded already.
|
||||||
|
*/
|
||||||
|
xbufp->len = xbufp->head[0].iov_len + xbufp->page_len +
|
||||||
|
xbufp->tail[0].iov_len;
|
||||||
|
req->rq_bytes_sent = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void xprt_init(struct rpc_xprt *xprt, struct net *net)
|
static void xprt_init(struct rpc_xprt *xprt, struct net *net)
|
||||||
{
|
{
|
||||||
kref_init(&xprt->kref);
|
kref_init(&xprt->kref);
|
||||||
|
|
Loading…
Reference in New Issue