IB/srp: Avoid duplicate connections
authorBart Van Assche <bvanassche@acm.org>
Fri, 14 Mar 2014 12:52:45 +0000 (13:52 +0100)
committerRoland Dreier <roland@purestorage.com>
Mon, 24 Mar 2014 17:05:31 +0000 (10:05 -0700)
The connection uniqueness check is performed before a new connection
is added to the target list. This patch protects both actions by a
mutex such that simultaneous writes from two different threads into the
"add_target" variable do not result in duplicate connections.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h

index 2ec9c05..3294f10 100644 (file)
@@ -2614,6 +2614,8 @@ static ssize_t srp_create_target(struct device *dev,
        target->tl_retry_count  = 7;
        target->queue_size      = SRP_DEFAULT_QUEUE_SIZE;
 
+       mutex_lock(&host->add_target_mutex);
+
        ret = srp_parse_options(buf, target);
        if (ret)
                goto err;
@@ -2682,7 +2684,11 @@ static ssize_t srp_create_target(struct device *dev,
                     be64_to_cpu(target->service_id),
                     target->path.sgid.raw, target->path.dgid.raw);
 
-       return count;
+       ret = count;
+
+out:
+       mutex_unlock(&host->add_target_mutex);
+       return ret;
 
 err_disconnect:
        srp_disconnect_target(target);
@@ -2698,8 +2704,7 @@ err_free_mem:
 
 err:
        scsi_host_put(target_host);
-
-       return ret;
+       goto out;
 }
 
 static DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);
@@ -2735,6 +2740,7 @@ static struct srp_host *srp_add_port(struct srp_device *device, u8 port)
        INIT_LIST_HEAD(&host->target_list);
        spin_lock_init(&host->target_lock);
        init_completion(&host->released);
+       mutex_init(&host->add_target_mutex);
        host->srp_dev = device;
        host->port = port;
 
index 5756810..aad27b7 100644 (file)
@@ -105,6 +105,7 @@ struct srp_host {
        spinlock_t              target_lock;
        struct completion       released;
        struct list_head        list;
+       struct mutex            add_target_mutex;
 };
 
 struct srp_request {