diff options
author | Tom Tucker <tom@opengridcomputing.com> | 2008-05-06 10:45:54 -0400 |
---|---|---|
committer | Tom Tucker <tom@opengridcomputing.com> | 2008-05-19 08:33:48 -0400 |
commit | 58e8f62137f1c55fe3d31234167660f2ce509297 (patch) | |
tree | 44f5b8731574db63d76f2c7bd4122d37c1cba540 /net/sunrpc/xprtrdma | |
parent | 5ac461a6f05499fa233ea43b1de80b679d1eec21 (diff) |
svcrdma: Fix error handling during listening endpoint creation
A listening endpoint isn't known to the generic transport switch until
the svc_create_xprt function returns without error. Calling
svc_xprt_put within the xpo_create function causes the module reference
count to be erroneously decremented.
Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
Diffstat (limited to 'net/sunrpc/xprtrdma')
-rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index e85ac77f4954..d9ed5f24c362 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -667,31 +667,27 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, | |||
667 | 667 | ||
668 | cma_xprt = rdma_create_xprt(serv, 1); | 668 | cma_xprt = rdma_create_xprt(serv, 1); |
669 | if (!cma_xprt) | 669 | if (!cma_xprt) |
670 | return ERR_PTR(ENOMEM); | 670 | return ERR_PTR(-ENOMEM); |
671 | xprt = &cma_xprt->sc_xprt; | 671 | xprt = &cma_xprt->sc_xprt; |
672 | 672 | ||
673 | listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP); | 673 | listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP); |
674 | if (IS_ERR(listen_id)) { | 674 | if (IS_ERR(listen_id)) { |
675 | svc_xprt_put(&cma_xprt->sc_xprt); | 675 | ret = PTR_ERR(listen_id); |
676 | dprintk("svcrdma: rdma_create_id failed = %ld\n", | 676 | dprintk("svcrdma: rdma_create_id failed = %d\n", ret); |
677 | PTR_ERR(listen_id)); | 677 | goto err0; |
678 | return (void *)listen_id; | ||
679 | } | 678 | } |
679 | |||
680 | ret = rdma_bind_addr(listen_id, sa); | 680 | ret = rdma_bind_addr(listen_id, sa); |
681 | if (ret) { | 681 | if (ret) { |
682 | rdma_destroy_id(listen_id); | ||
683 | svc_xprt_put(&cma_xprt->sc_xprt); | ||
684 | dprintk("svcrdma: rdma_bind_addr failed = %d\n", ret); | 682 | dprintk("svcrdma: rdma_bind_addr failed = %d\n", ret); |
685 | return ERR_PTR(ret); | 683 | goto err1; |
686 | } | 684 | } |
687 | cma_xprt->sc_cm_id = listen_id; | 685 | cma_xprt->sc_cm_id = listen_id; |
688 | 686 | ||
689 | ret = rdma_listen(listen_id, RPCRDMA_LISTEN_BACKLOG); | 687 | ret = rdma_listen(listen_id, RPCRDMA_LISTEN_BACKLOG); |
690 | if (ret) { | 688 | if (ret) { |
691 | rdma_destroy_id(listen_id); | ||
692 | svc_xprt_put(&cma_xprt->sc_xprt); | ||
693 | dprintk("svcrdma: rdma_listen failed = %d\n", ret); | 689 | dprintk("svcrdma: rdma_listen failed = %d\n", ret); |
694 | return ERR_PTR(ret); | 690 | goto err1; |
695 | } | 691 | } |
696 | 692 | ||
697 | /* | 693 | /* |
@@ -702,6 +698,12 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, | |||
702 | svc_xprt_set_local(&cma_xprt->sc_xprt, sa, salen); | 698 | svc_xprt_set_local(&cma_xprt->sc_xprt, sa, salen); |
703 | 699 | ||
704 | return &cma_xprt->sc_xprt; | 700 | return &cma_xprt->sc_xprt; |
701 | |||
702 | err1: | ||
703 | rdma_destroy_id(listen_id); | ||
704 | err0: | ||
705 | kfree(cma_xprt); | ||
706 | return ERR_PTR(ret); | ||
705 | } | 707 | } |
706 | 708 | ||
707 | /* | 709 | /* |