summaryrefslogtreecommitdiff
path: root/drivers/xen
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2015-05-11 05:31:10 +0300
committerNicholas Bellinger <nab@linux-iscsi.org>2015-06-01 10:24:33 +0300
commit6bb826121be244a5a3c8bd8b7d45c47df18810b7 (patch)
tree7a75624e4801567a4133bc5b373ed67dd1db1cbb /drivers/xen
parent9fcb57f39c0cde70bcccdc1d998d3060297e911c (diff)
downloadlinux-6bb826121be244a5a3c8bd8b7d45c47df18810b7.tar.xz
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.c27
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,
struct list_head *head = &(info->v2p_entry_lists);
unsigned long flags;
char *lunp;
- unsigned int lun;
+ unsigned int unpacked_lun;
+ struct se_lun *se_lun;
struct scsiback_tpg *tpg_entry, *tpg = NULL;
char *error = "doesn't exist";
@@ -877,7 +878,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
}
*lunp = 0;
lunp++;
- if (kstrtouint(lunp, 10, &lun) || lun >= TRANSPORT_MAX_LUNS_PER_TPG) {
+ if (kstrtouint(lunp, 10, &unpacked_lun) || unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG) {
pr_err("lun number not valid: %s\n", lunp);
return -EINVAL;
}
@@ -886,15 +887,17 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
list_for_each_entry(tpg_entry, &scsiback_list, tv_tpg_list) {
if (!strcmp(phy, tpg_entry->tport->tport_name) ||
!strcmp(phy, tpg_entry->param_alias)) {
- spin_lock(&tpg_entry->se_tpg.tpg_lun_lock);
- if (tpg_entry->se_tpg.tpg_lun_list[lun]->lun_status ==
- TRANSPORT_LUN_STATUS_ACTIVE) {
- if (!tpg_entry->tpg_nexus)
- error = "nexus undefined";
- else
- tpg = tpg_entry;
+ mutex_lock(&tpg_entry->se_tpg.tpg_lun_mutex);
+ hlist_for_each_entry(se_lun, &tpg_entry->se_tpg.tpg_lun_hlist, link) {
+ if (se_lun->unpacked_lun == unpacked_lun) {
+ if (!tpg_entry->tpg_nexus)
+ error = "nexus undefined";
+ else
+ tpg = tpg_entry;
+ break;
+ }
}
- spin_unlock(&tpg_entry->se_tpg.tpg_lun_lock);
+ mutex_unlock(&tpg_entry->se_tpg.tpg_lun_mutex);
break;
}
}
@@ -906,7 +909,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
mutex_unlock(&scsiback_mutex);
if (!tpg) {
- pr_err("%s:%d %s\n", phy, lun, error);
+ pr_err("%s:%d %s\n", phy, unpacked_lun, error);
return -ENODEV;
}
@@ -934,7 +937,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info,
kref_init(&new->kref);
new->v = *v;
new->tpg = tpg;
- new->lun = lun;
+ new->lun = unpacked_lun;
list_add_tail(&new->l, head);
out: