aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2014-03-14 08:52:45 -0400
committerRoland Dreier <roland@purestorage.com>2014-03-24 13:05:31 -0400
commit2d7091bcf6f893a9b1a2add357c637055eae4e68 (patch)
tree10af70bb397f7c23f3d6f581a37a1a557d53abbd /drivers/infiniband
parente7ffde0164b1a580f66ea3b95081626107931d3c (diff)
IB/srp: Avoid duplicate connections
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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c12
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2ec9c05814f6..3294f10316a0 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -2614,6 +2614,8 @@ static ssize_t srp_create_target(struct device *dev,
2614 target->tl_retry_count = 7; 2614 target->tl_retry_count = 7;
2615 target->queue_size = SRP_DEFAULT_QUEUE_SIZE; 2615 target->queue_size = SRP_DEFAULT_QUEUE_SIZE;
2616 2616
2617 mutex_lock(&host->add_target_mutex);
2618
2617 ret = srp_parse_options(buf, target); 2619 ret = srp_parse_options(buf, target);
2618 if (ret) 2620 if (ret)
2619 goto err; 2621 goto err;
@@ -2682,7 +2684,11 @@ static ssize_t srp_create_target(struct device *dev,
2682 be64_to_cpu(target->service_id), 2684 be64_to_cpu(target->service_id),
2683 target->path.sgid.raw, target->path.dgid.raw); 2685 target->path.sgid.raw, target->path.dgid.raw);
2684 2686
2685 return count; 2687 ret = count;
2688
2689out:
2690 mutex_unlock(&host->add_target_mutex);
2691 return ret;
2686 2692
2687err_disconnect: 2693err_disconnect:
2688 srp_disconnect_target(target); 2694 srp_disconnect_target(target);
@@ -2698,8 +2704,7 @@ err_free_mem:
2698 2704
2699err: 2705err:
2700 scsi_host_put(target_host); 2706 scsi_host_put(target_host);
2701 2707 goto out;
2702 return ret;
2703} 2708}
2704 2709
2705static DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target); 2710static 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)
2735 INIT_LIST_HEAD(&host->target_list); 2740 INIT_LIST_HEAD(&host->target_list);
2736 spin_lock_init(&host->target_lock); 2741 spin_lock_init(&host->target_lock);
2737 init_completion(&host->released); 2742 init_completion(&host->released);
2743 mutex_init(&host->add_target_mutex);
2738 host->srp_dev = device; 2744 host->srp_dev = device;
2739 host->port = port; 2745 host->port = port;
2740 2746
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 575681063f38..aad27b7b4a46 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -105,6 +105,7 @@ struct srp_host {
105 spinlock_t target_lock; 105 spinlock_t target_lock;
106 struct completion released; 106 struct completion released;
107 struct list_head list; 107 struct list_head list;
108 struct mutex add_target_mutex;
108}; 109};
109 110
110struct srp_request { 111struct srp_request {