diff options
author | Trond Myklebust <trondmy@gmail.com> | 2019-10-17 09:02:19 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-10-30 12:04:35 -0400 |
commit | 875f0706accd6501c3209bb99df8573171fb5d75 (patch) | |
tree | e24cf1a2f3194e97452a8a8907ffbfd8e543cb0c /net | |
parent | 9e5eefba3d098d66defa1ce59a34a41a96f49771 (diff) |
SUNRPC: The TCP back channel mustn't disappear while requests are outstanding
If there are TCP back channel requests being processed by the
server threads, then we should hold a reference to the transport
to ensure it doesn't get freed from underneath us.
Reported-by: Neil Brown <neilb@suse.de>
Fixes: 2ea24497a1b3 ("SUNRPC: RPC callbacks may be split across several..")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/backchannel_rqst.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 339e8c077c2d..7eb251372f94 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
@@ -307,8 +307,8 @@ void xprt_free_bc_rqst(struct rpc_rqst *req) | |||
307 | */ | 307 | */ |
308 | dprintk("RPC: Last session removed req=%p\n", req); | 308 | dprintk("RPC: Last session removed req=%p\n", req); |
309 | xprt_free_allocation(req); | 309 | xprt_free_allocation(req); |
310 | return; | ||
311 | } | 310 | } |
311 | xprt_put(xprt); | ||
312 | } | 312 | } |
313 | 313 | ||
314 | /* | 314 | /* |
@@ -339,7 +339,7 @@ found: | |||
339 | spin_unlock(&xprt->bc_pa_lock); | 339 | spin_unlock(&xprt->bc_pa_lock); |
340 | if (new) { | 340 | if (new) { |
341 | if (req != new) | 341 | if (req != new) |
342 | xprt_free_bc_rqst(new); | 342 | xprt_free_allocation(new); |
343 | break; | 343 | break; |
344 | } else if (req) | 344 | } else if (req) |
345 | break; | 345 | break; |
@@ -368,6 +368,7 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) | |||
368 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); | 368 | set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); |
369 | 369 | ||
370 | dprintk("RPC: add callback request to list\n"); | 370 | dprintk("RPC: add callback request to list\n"); |
371 | xprt_get(xprt); | ||
371 | spin_lock(&bc_serv->sv_cb_lock); | 372 | spin_lock(&bc_serv->sv_cb_lock); |
372 | list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); | 373 | list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); |
373 | wake_up(&bc_serv->sv_cb_waitq); | 374 | wake_up(&bc_serv->sv_cb_waitq); |