diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-05-10 22:31:10 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-06-01 03:24:33 -0400 |
commit | 6bb826121be244a5a3c8bd8b7d45c47df18810b7 (patch) | |
tree | 7a75624e4801567a4133bc5b373ed67dd1db1cbb /drivers/xen | |
parent | 9fcb57f39c0cde70bcccdc1d998d3060297e911c (diff) |
target: Convert se_portal_group->tpg_lun_list[] to RCU hlist
This patch converts the fixed size se_portal_group->tpg_lun_list[]
to use modern RCU with hlist_head in order to support an arbitary
number of se_lun ports per target endpoint.
It includes dropping core_tpg_alloc_lun() from core_dev_add_lun(),
and calling it directly from target_fabric_make_lun() to allocate
a new se_lun. And add a new target_fabric_port_release() configfs
item callback to invoke kfree_rcu() to release memory during
se_lun->lun_group shutdown.
Also now that se_node_acl->lun_entry_hlist is using RCU, convert
existing tpg_lun_lock to struct mutex so core_tpg_add_node_to_devs()
can perform RCU updater logic without releasing ->tpg_lun_mutex.
Also, drop core_tpg_clear_object_luns() and it's single consumer
in iscsi-target, which is duplicating TPG LUN shutdown logic and
is current code results in a NOP.
Finally, sbp-target and xen-scsiback fabric driver conversions are
included, which are required due to the non-standard way they use
->tpg_lun_hlist.
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Chris Boot <bootc@bootc.net>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/xen-scsiback.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 8b7dd47abd8d..555033bd9239 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c | |||
@@ -866,7 +866,8 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, | |||
866 | struct list_head *head = &(info->v2p_entry_lists); | 866 | struct list_head *head = &(info->v2p_entry_lists); |
867 | unsigned long flags; | 867 | unsigned long flags; |
868 | char *lunp; | 868 | char *lunp; |
869 | unsigned int lun; | 869 | unsigned int unpacked_lun; |
870 | struct se_lun *se_lun; | ||
870 | struct scsiback_tpg *tpg_entry, *tpg = NULL; | 871 | struct scsiback_tpg *tpg_entry, *tpg = NULL; |
871 | char *error = "doesn't exist"; | 872 | char *error = "doesn't exist"; |
872 | 873 | ||
@@ -877,7 +878,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, | |||
877 | } | 878 | } |
878 | *lunp = 0; | 879 | *lunp = 0; |
879 | lunp++; | 880 | lunp++; |
880 | if (kstrtouint(lunp, 10, &lun) || lun >= TRANSPORT_MAX_LUNS_PER_TPG) { | 881 | if (kstrtouint(lunp, 10, &unpacked_lun) || unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) { |
881 | pr_err("lun number not valid: %s\n", lunp); | 882 | pr_err("lun number not valid: %s\n", lunp); |
882 | return -EINVAL; | 883 | return -EINVAL; |
883 | } | 884 | } |
@@ -886,15 +887,17 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, | |||
886 | list_for_each_entry(tpg_entry, &scsiback_list, tv_tpg_list) { | 887 | list_for_each_entry(tpg_entry, &scsiback_list, tv_tpg_list) { |
887 | if (!strcmp(phy, tpg_entry->tport->tport_name) || | 888 | if (!strcmp(phy, tpg_entry->tport->tport_name) || |
888 | !strcmp(phy, tpg_entry->param_alias)) { | 889 | !strcmp(phy, tpg_entry->param_alias)) { |
889 | spin_lock(&tpg_entry->se_tpg.tpg_lun_lock); | 890 | mutex_lock(&tpg_entry->se_tpg.tpg_lun_mutex); |
890 | if (tpg_entry->se_tpg.tpg_lun_list[lun]->lun_status == | 891 | hlist_for_each_entry(se_lun, &tpg_entry->se_tpg.tpg_lun_hlist, link) { |
891 | TRANSPORT_LUN_STATUS_ACTIVE) { | 892 | if (se_lun->unpacked_lun == unpacked_lun) { |
892 | if (!tpg_entry->tpg_nexus) | 893 | if (!tpg_entry->tpg_nexus) |
893 | error = "nexus undefined"; | 894 | error = "nexus undefined"; |
894 | else | 895 | else |
895 | tpg = tpg_entry; | 896 | tpg = tpg_entry; |
897 | break; | ||
898 | } | ||
896 | } | 899 | } |
897 | spin_unlock(&tpg_entry->se_tpg.tpg_lun_lock); | 900 | mutex_unlock(&tpg_entry->se_tpg.tpg_lun_mutex); |
898 | break; | 901 | break; |
899 | } | 902 | } |
900 | } | 903 | } |
@@ -906,7 +909,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, | |||
906 | mutex_unlock(&scsiback_mutex); | 909 | mutex_unlock(&scsiback_mutex); |
907 | 910 | ||
908 | if (!tpg) { | 911 | if (!tpg) { |
909 | pr_err("%s:%d %s\n", phy, lun, error); | 912 | pr_err("%s:%d %s\n", phy, unpacked_lun, error); |
910 | return -ENODEV; | 913 | return -ENODEV; |
911 | } | 914 | } |
912 | 915 | ||
@@ -934,7 +937,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, | |||
934 | kref_init(&new->kref); | 937 | kref_init(&new->kref); |
935 | new->v = *v; | 938 | new->v = *v; |
936 | new->tpg = tpg; | 939 | new->tpg = tpg; |
937 | new->lun = lun; | 940 | new->lun = unpacked_lun; |
938 | list_add_tail(&new->l, head); | 941 | list_add_tail(&new->l, head); |
939 | 942 | ||
940 | out: | 943 | out: |