diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-06-04 22:37:10 +0300 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-06-05 18:15:43 +0300 |
commit | 0d2a970d0ae55086520e1e58e572a7acd519429c (patch) | |
tree | b91159e4d38c5c9599cfb7500395729ced35a245 /net/sunrpc/svc.c | |
parent | 1dddda86c056ab4cf49e4206824a9de3e0c4159a (diff) | |
download | linux-0d2a970d0ae55086520e1e58e572a7acd519429c.tar.xz |
SUNRPC: Fix a backchannel race
We need to allow the server to send a new request immediately after we've
replied to the previous one. Right now, there is a window between the
send and the release of the old request in rpc_put_task(), where the
server could send us a new backchannel RPC call, and we have no
request to service it.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 51c8cad5e765..b47f02f60b9c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1351,6 +1351,7 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *resv = &rqstp->rq_res.head[0]; struct rpc_task *task; + int proc_error; int error; dprintk("svc: %s(%p)\n", __func__, req); @@ -1382,7 +1383,10 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, svc_getnl(argv); /* CALLDIR */ /* Parse and execute the bc call */ - if (!svc_process_common(rqstp, argv, resv)) { + proc_error = svc_process_common(rqstp, argv, resv); + + atomic_inc(&req->rq_xprt->bc_free_slots); + if (!proc_error) { /* Processing error: drop the request */ xprt_free_bc_request(req); return 0; |