diff options
author | Bart Van Assche <bvanassche@acm.org> | 2014-03-14 08:52:45 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-03-24 13:05:31 -0400 |
commit | 2d7091bcf6f893a9b1a2add357c637055eae4e68 (patch) | |
tree | 10af70bb397f7c23f3d6f581a37a1a557d53abbd /drivers/infiniband | |
parent | e7ffde0164b1a580f66ea3b95081626107931d3c (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.c | 12 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 1 |
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 | |||
2689 | out: | ||
2690 | mutex_unlock(&host->add_target_mutex); | ||
2691 | return ret; | ||
2686 | 2692 | ||
2687 | err_disconnect: | 2693 | err_disconnect: |
2688 | srp_disconnect_target(target); | 2694 | srp_disconnect_target(target); |
@@ -2698,8 +2704,7 @@ err_free_mem: | |||
2698 | 2704 | ||
2699 | err: | 2705 | err: |
2700 | scsi_host_put(target_host); | 2706 | scsi_host_put(target_host); |
2701 | 2707 | goto out; | |
2702 | return ret; | ||
2703 | } | 2708 | } |
2704 | 2709 | ||
2705 | static DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target); | 2710 | 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) | |||
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 | ||
110 | struct srp_request { | 111 | struct srp_request { |