Skip to content

Commit 7474f52

Browse files
author
Nicholas Bellinger
committed
tcm_qla2xxx: Perform configfs depend/undepend for base_tpg
This patch performs configfs_depend_item() during TPG enable for base_tpg (eg: non-NPIV) ports, and configfs_undepend_item() during TPG disable for base_tpg. This is done to ensure that any attempt to configfs rmdir a base_tpg with active NPIV ports will fail with -EBUSY, until all associated NPIV ports have been explicitly shutdown and base_tpg disabled. Note that the actual configfs_[un]depend_item() is done from seperate process context, as these are not intended to be called directly from configfs callbacks. Cc: Sawan Chandak <sawan.chandak@qlogic.com> Cc: Quinn Tran <quinn.tran@qlogic.com> Cc: Saurav Kashyap <saurav.kashyap@qlogic.com> Cc: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
1 parent 394d62b commit 7474f52

File tree

2 files changed

+61
-14
lines changed

2 files changed

+61
-14
lines changed

drivers/scsi/qla2xxx/tcm_qla2xxx.c

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -941,15 +941,41 @@ static ssize_t tcm_qla2xxx_tpg_show_enable(
941941
atomic_read(&tpg->lport_tpg_enabled));
942942
}
943943

944+
static void tcm_qla2xxx_depend_tpg(struct work_struct *work)
945+
{
946+
struct tcm_qla2xxx_tpg *base_tpg = container_of(work,
947+
struct tcm_qla2xxx_tpg, tpg_base_work);
948+
struct se_portal_group *se_tpg = &base_tpg->se_tpg;
949+
struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha;
950+
951+
if (!configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys,
952+
&se_tpg->tpg_group.cg_item)) {
953+
atomic_set(&base_tpg->lport_tpg_enabled, 1);
954+
qlt_enable_vha(base_vha);
955+
}
956+
complete(&base_tpg->tpg_base_comp);
957+
}
958+
959+
static void tcm_qla2xxx_undepend_tpg(struct work_struct *work)
960+
{
961+
struct tcm_qla2xxx_tpg *base_tpg = container_of(work,
962+
struct tcm_qla2xxx_tpg, tpg_base_work);
963+
struct se_portal_group *se_tpg = &base_tpg->se_tpg;
964+
struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha;
965+
966+
if (!qlt_stop_phase1(base_vha->vha_tgt.qla_tgt)) {
967+
atomic_set(&base_tpg->lport_tpg_enabled, 0);
968+
configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys,
969+
&se_tpg->tpg_group.cg_item);
970+
}
971+
complete(&base_tpg->tpg_base_comp);
972+
}
973+
944974
static ssize_t tcm_qla2xxx_tpg_store_enable(
945975
struct se_portal_group *se_tpg,
946976
const char *page,
947977
size_t count)
948978
{
949-
struct se_wwn *se_wwn = se_tpg->se_tpg_wwn;
950-
struct tcm_qla2xxx_lport *lport = container_of(se_wwn,
951-
struct tcm_qla2xxx_lport, lport_wwn);
952-
struct scsi_qla_host *vha = lport->qla_vha;
953979
struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
954980
struct tcm_qla2xxx_tpg, se_tpg);
955981
unsigned long op;
@@ -964,19 +990,28 @@ static ssize_t tcm_qla2xxx_tpg_store_enable(
964990
pr_err("Illegal value for tpg_enable: %lu\n", op);
965991
return -EINVAL;
966992
}
967-
968993
if (op) {
969-
atomic_set(&tpg->lport_tpg_enabled, 1);
970-
qlt_enable_vha(vha);
994+
if (atomic_read(&tpg->lport_tpg_enabled))
995+
return -EEXIST;
996+
997+
INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_depend_tpg);
971998
} else {
972-
if (!vha->vha_tgt.qla_tgt) {
973-
pr_err("struct qla_hw_data *vha->vha_tgt.qla_tgt is NULL\n");
974-
return -ENODEV;
975-
}
976-
atomic_set(&tpg->lport_tpg_enabled, 0);
977-
qlt_stop_phase1(vha->vha_tgt.qla_tgt);
999+
if (!atomic_read(&tpg->lport_tpg_enabled))
1000+
return count;
1001+
1002+
INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_undepend_tpg);
9781003
}
1004+
init_completion(&tpg->tpg_base_comp);
1005+
schedule_work(&tpg->tpg_base_work);
1006+
wait_for_completion(&tpg->tpg_base_comp);
9791007

1008+
if (op) {
1009+
if (!atomic_read(&tpg->lport_tpg_enabled))
1010+
return -ENODEV;
1011+
} else {
1012+
if (atomic_read(&tpg->lport_tpg_enabled))
1013+
return -EPERM;
1014+
}
9801015
return count;
9811016
}
9821017

@@ -1703,13 +1738,23 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
17031738
struct scsi_qla_host *npiv_vha;
17041739
struct tcm_qla2xxx_lport *lport =
17051740
(struct tcm_qla2xxx_lport *)target_lport_ptr;
1741+
struct tcm_qla2xxx_lport *base_lport =
1742+
(struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr;
1743+
struct tcm_qla2xxx_tpg *base_tpg;
17061744
struct fc_vport_identifiers vport_id;
17071745

17081746
if (!qla_tgt_mode_enabled(base_vha)) {
17091747
pr_err("qla2xxx base_vha not enabled for target mode\n");
17101748
return -EPERM;
17111749
}
17121750

1751+
if (!base_lport || !base_lport->tpg_1 ||
1752+
!atomic_read(&base_lport->tpg_1->lport_tpg_enabled)) {
1753+
pr_err("qla2xxx base_lport or tpg_1 not available\n");
1754+
return -EPERM;
1755+
}
1756+
base_tpg = base_lport->tpg_1;
1757+
17131758
memset(&vport_id, 0, sizeof(vport_id));
17141759
vport_id.port_name = npiv_wwpn;
17151760
vport_id.node_name = npiv_wwnn;
@@ -1728,7 +1773,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
17281773
npiv_vha = (struct scsi_qla_host *)vport->dd_data;
17291774
npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr;
17301775
lport->qla_vha = npiv_vha;
1731-
17321776
scsi_host_get(npiv_vha->host);
17331777
return 0;
17341778
}

drivers/scsi/qla2xxx/tcm_qla2xxx.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ struct tcm_qla2xxx_tpg {
4343
struct tcm_qla2xxx_tpg_attrib tpg_attrib;
4444
/* Returned by tcm_qla2xxx_make_tpg() */
4545
struct se_portal_group se_tpg;
46+
/* Items for dealing with configfs_depend_item */
47+
struct completion tpg_base_comp;
48+
struct work_struct tpg_base_work;
4649
};
4750

4851
struct tcm_qla2xxx_fc_loopid {

0 commit comments

Comments
 (0)