]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/infiniband/core/cma.c
RDMA/cma: rdma_bind_addr() leaks a cma_dev reference count
[linux-2.6.git] / 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;
 }