RDMA/cma: rdma_bind_addr() leaks a cma_dev reference count
authorKrishna Kumar <krkumar2@in.ibm.com>
Tue, 24 Oct 2006 20:22:28 +0000 (13:22 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 31 Oct 2006 04:52:51 +0000 (20:52 -0800)
rdma_bind_addr() leaks a cma_dev reference count in failure case.

Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
drivers/infiniband/core/cma.c

index 9ae4f3a67c704639bfee110773d22c58d536ea2c..d8ca3c1368b5f3df3c2c0b65fbbe7339f33121f0 100644 (file)
@@ -1762,22 +1762,29 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 
        if (!cma_any_addr(addr)) {
                ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
-               if (!ret) {
-                       mutex_lock(&lock);
-                       ret = cma_acquire_dev(id_priv);
-                       mutex_unlock(&lock);
-               }
                if (ret)
-                       goto err;
+                       goto err1;
+
+               mutex_lock(&lock);
+               ret = cma_acquire_dev(id_priv);
+               mutex_unlock(&lock);
+               if (ret)
+                       goto err1;
        }
 
        memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
        ret = cma_get_port(id_priv);
        if (ret)
-               goto err;
+               goto err2;
 
        return 0;
-err:
+err2:
+       if (!cma_any_addr(addr)) {
+               mutex_lock(&lock);
+               cma_detach_from_dev(id_priv);
+               mutex_unlock(&lock);
+       }
+err1:
        cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE);
        return ret;
 }