diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-16 23:25:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-16 23:25:52 -0400 |
commit | 41ef72181a9fde78f13d0966e3019fb37f6058e4 (patch) | |
tree | a2f6d64b8c9ffb4b2e59042891578eef91764113 /net | |
parent | 9c514bedbe6948f31d29c53aceb9234c1484ae69 (diff) | |
parent | 8c7245abda877d4689b3371db8ae2a4400d7d9ce (diff) |
Merge tag 'nfsd-4.7-1' of git://linux-nfs.org/~bfields/linux
Pull nfsd bugfixes from Bruce Fields:
"Oleg Drokin found and fixed races in the nfsd4 state code that go back
to the big nfs4_lock_state removal around 3.17 (but that were also
probably hard to reproduce before client changes in 3.20 allowed the
client to perform parallel opens).
Also fix a 4.1 backchannel crash due to rpc multipath changes in 4.6.
Trond acked the client-side rpc fixes going through my tree"
* tag 'nfsd-4.7-1' of git://linux-nfs.org/~bfields/linux:
nfsd: Make init_open_stateid() a bit more whole
nfsd: Extend the mutex holding region around in nfsd4_process_open2()
nfsd: Always lock state exclusively.
rpc: share one xps between all backchannels
nfsd4/rpc: move backchannel create logic into rpc code
SUNRPC: fix xprt leak on xps allocation failure
nfsd: Fix NFSD_MDS_PR_KEY on 32-bit by adding ULL postfix
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/clnt.c | 31 | ||||
-rw-r--r-- | net/sunrpc/svc_xprt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 1 |
3 files changed, 28 insertions, 6 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 06b4df9faaa1..2808d550d273 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -446,16 +446,27 @@ out_no_rpciod: | |||
446 | return ERR_PTR(err); | 446 | return ERR_PTR(err); |
447 | } | 447 | } |
448 | 448 | ||
449 | struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, | 449 | static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, |
450 | struct rpc_xprt *xprt) | 450 | struct rpc_xprt *xprt) |
451 | { | 451 | { |
452 | struct rpc_clnt *clnt = NULL; | 452 | struct rpc_clnt *clnt = NULL; |
453 | struct rpc_xprt_switch *xps; | 453 | struct rpc_xprt_switch *xps; |
454 | 454 | ||
455 | xps = xprt_switch_alloc(xprt, GFP_KERNEL); | 455 | if (args->bc_xprt && args->bc_xprt->xpt_bc_xps) { |
456 | if (xps == NULL) | 456 | WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP); |
457 | return ERR_PTR(-ENOMEM); | 457 | xps = args->bc_xprt->xpt_bc_xps; |
458 | 458 | xprt_switch_get(xps); | |
459 | } else { | ||
460 | xps = xprt_switch_alloc(xprt, GFP_KERNEL); | ||
461 | if (xps == NULL) { | ||
462 | xprt_put(xprt); | ||
463 | return ERR_PTR(-ENOMEM); | ||
464 | } | ||
465 | if (xprt->bc_xprt) { | ||
466 | xprt_switch_get(xps); | ||
467 | xprt->bc_xprt->xpt_bc_xps = xps; | ||
468 | } | ||
469 | } | ||
459 | clnt = rpc_new_client(args, xps, xprt, NULL); | 470 | clnt = rpc_new_client(args, xps, xprt, NULL); |
460 | if (IS_ERR(clnt)) | 471 | if (IS_ERR(clnt)) |
461 | return clnt; | 472 | return clnt; |
@@ -483,7 +494,6 @@ struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args, | |||
483 | 494 | ||
484 | return clnt; | 495 | return clnt; |
485 | } | 496 | } |
486 | EXPORT_SYMBOL_GPL(rpc_create_xprt); | ||
487 | 497 | ||
488 | /** | 498 | /** |
489 | * rpc_create - create an RPC client and transport with one call | 499 | * rpc_create - create an RPC client and transport with one call |
@@ -509,6 +519,15 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
509 | }; | 519 | }; |
510 | char servername[48]; | 520 | char servername[48]; |
511 | 521 | ||
522 | if (args->bc_xprt) { | ||
523 | WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP); | ||
524 | xprt = args->bc_xprt->xpt_bc_xprt; | ||
525 | if (xprt) { | ||
526 | xprt_get(xprt); | ||
527 | return rpc_create_xprt(args, xprt); | ||
528 | } | ||
529 | } | ||
530 | |||
512 | if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS) | 531 | if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS) |
513 | xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS; | 532 | xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS; |
514 | if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT) | 533 | if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT) |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index f5572e31d518..4f01f63102ee 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -136,6 +136,8 @@ static void svc_xprt_free(struct kref *kref) | |||
136 | /* See comment on corresponding get in xs_setup_bc_tcp(): */ | 136 | /* See comment on corresponding get in xs_setup_bc_tcp(): */ |
137 | if (xprt->xpt_bc_xprt) | 137 | if (xprt->xpt_bc_xprt) |
138 | xprt_put(xprt->xpt_bc_xprt); | 138 | xprt_put(xprt->xpt_bc_xprt); |
139 | if (xprt->xpt_bc_xps) | ||
140 | xprt_switch_put(xprt->xpt_bc_xps); | ||
139 | xprt->xpt_ops->xpo_free(xprt); | 141 | xprt->xpt_ops->xpo_free(xprt); |
140 | module_put(owner); | 142 | module_put(owner); |
141 | } | 143 | } |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 2d3e0c42361e..7e2b2fa189c3 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -3057,6 +3057,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
3057 | return xprt; | 3057 | return xprt; |
3058 | 3058 | ||
3059 | args->bc_xprt->xpt_bc_xprt = NULL; | 3059 | args->bc_xprt->xpt_bc_xprt = NULL; |
3060 | args->bc_xprt->xpt_bc_xps = NULL; | ||
3060 | xprt_put(xprt); | 3061 | xprt_put(xprt); |
3061 | ret = ERR_PTR(-EINVAL); | 3062 | ret = ERR_PTR(-EINVAL); |
3062 | out_err: | 3063 | out_err: |