aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/loopback
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-11-26 08:58:57 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2014-12-02 00:36:21 -0500
commit506787a2c7daed45f0a213674ca706cbc83a9089 (patch)
treed8734240e8977854cc1845d7fa173d76bc3d923c /drivers/target/loopback
parent4b2f57e5ced40e91cbf8886d7dc40a9474d2f5c0 (diff)
tcm_loop: Fix wrong I_T nexus association
tcm_loop has the I_T nexus associated with the HBA. This causes commands to become misdirected if the HBA has more than one target portal group; any command is then being sent to the first target portal group instead of the correct one. The nexus needs to be associated with the target portal group instead. Signed-off-by: Hannes Reinecke <hare@suse.de> Cc: <stable@vger.kernel.org> # 3.0+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/loopback')
-rw-r--r--drivers/target/loopback/tcm_loop.c66
-rw-r--r--drivers/target/loopback/tcm_loop.h7
2 files changed, 24 insertions, 49 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index ab3ab27d49b7..0be83e788df2 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -190,7 +190,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
190 set_host_byte(sc, DID_TRANSPORT_DISRUPTED); 190 set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
191 goto out_done; 191 goto out_done;
192 } 192 }
193 tl_nexus = tl_hba->tl_nexus; 193 tl_nexus = tl_tpg->tl_nexus;
194 if (!tl_nexus) { 194 if (!tl_nexus) {
195 scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" 195 scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
196 " does not exist\n"); 196 " does not exist\n");
@@ -270,16 +270,26 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
270 * to struct scsi_device 270 * to struct scsi_device
271 */ 271 */
272static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, 272static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
273 struct tcm_loop_nexus *tl_nexus,
274 int lun, int task, enum tcm_tmreq_table tmr) 273 int lun, int task, enum tcm_tmreq_table tmr)
275{ 274{
276 struct se_cmd *se_cmd = NULL; 275 struct se_cmd *se_cmd = NULL;
277 struct se_session *se_sess; 276 struct se_session *se_sess;
278 struct se_portal_group *se_tpg; 277 struct se_portal_group *se_tpg;
278 struct tcm_loop_nexus *tl_nexus;
279 struct tcm_loop_cmd *tl_cmd = NULL; 279 struct tcm_loop_cmd *tl_cmd = NULL;
280 struct tcm_loop_tmr *tl_tmr = NULL; 280 struct tcm_loop_tmr *tl_tmr = NULL;
281 int ret = TMR_FUNCTION_FAILED, rc; 281 int ret = TMR_FUNCTION_FAILED, rc;
282 282
283 /*
284 * Locate the tl_nexus and se_sess pointers
285 */
286 tl_nexus = tl_tpg->tl_nexus;
287 if (!tl_nexus) {
288 pr_err("Unable to perform device reset without"
289 " active I_T Nexus\n");
290 return ret;
291 }
292
283 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL); 293 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
284 if (!tl_cmd) { 294 if (!tl_cmd) {
285 pr_err("Unable to allocate memory for tl_cmd\n"); 295 pr_err("Unable to allocate memory for tl_cmd\n");
@@ -295,7 +305,7 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
295 305
296 se_cmd = &tl_cmd->tl_se_cmd; 306 se_cmd = &tl_cmd->tl_se_cmd;
297 se_tpg = &tl_tpg->tl_se_tpg; 307 se_tpg = &tl_tpg->tl_se_tpg;
298 se_sess = tl_nexus->se_sess; 308 se_sess = tl_tpg->tl_nexus->se_sess;
299 /* 309 /*
300 * Initialize struct se_cmd descriptor from target_core_mod infrastructure 310 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
301 */ 311 */
@@ -340,7 +350,6 @@ release:
340static int tcm_loop_abort_task(struct scsi_cmnd *sc) 350static int tcm_loop_abort_task(struct scsi_cmnd *sc)
341{ 351{
342 struct tcm_loop_hba *tl_hba; 352 struct tcm_loop_hba *tl_hba;
343 struct tcm_loop_nexus *tl_nexus;
344 struct tcm_loop_tpg *tl_tpg; 353 struct tcm_loop_tpg *tl_tpg;
345 int ret = FAILED; 354 int ret = FAILED;
346 355
@@ -348,21 +357,8 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc)
348 * Locate the tcm_loop_hba_t pointer 357 * Locate the tcm_loop_hba_t pointer
349 */ 358 */
350 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); 359 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
351 /*
352 * Locate the tl_nexus and se_sess pointers
353 */
354 tl_nexus = tl_hba->tl_nexus;
355 if (!tl_nexus) {
356 pr_err("Unable to perform device reset without"
357 " active I_T Nexus\n");
358 return FAILED;
359 }
360
361 /*
362 * Locate the tl_tpg pointer from TargetID in sc->device->id
363 */
364 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; 360 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
365 ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun, 361 ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
366 sc->request->tag, TMR_ABORT_TASK); 362 sc->request->tag, TMR_ABORT_TASK);
367 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; 363 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
368} 364}
@@ -374,7 +370,6 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc)
374static int tcm_loop_device_reset(struct scsi_cmnd *sc) 370static int tcm_loop_device_reset(struct scsi_cmnd *sc)
375{ 371{
376 struct tcm_loop_hba *tl_hba; 372 struct tcm_loop_hba *tl_hba;
377 struct tcm_loop_nexus *tl_nexus;
378 struct tcm_loop_tpg *tl_tpg; 373 struct tcm_loop_tpg *tl_tpg;
379 int ret = FAILED; 374 int ret = FAILED;
380 375
@@ -382,20 +377,9 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
382 * Locate the tcm_loop_hba_t pointer 377 * Locate the tcm_loop_hba_t pointer
383 */ 378 */
384 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); 379 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
385 /*
386 * Locate the tl_nexus and se_sess pointers
387 */
388 tl_nexus = tl_hba->tl_nexus;
389 if (!tl_nexus) {
390 pr_err("Unable to perform device reset without"
391 " active I_T Nexus\n");
392 return FAILED;
393 }
394 /*
395 * Locate the tl_tpg pointer from TargetID in sc->device->id
396 */
397 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; 380 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
398 ret = tcm_loop_issue_tmr(tl_tpg, tl_nexus, sc->device->lun, 381
382 ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
399 0, TMR_LUN_RESET); 383 0, TMR_LUN_RESET);
400 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; 384 return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
401} 385}
@@ -1005,8 +989,8 @@ static int tcm_loop_make_nexus(
1005 struct tcm_loop_nexus *tl_nexus; 989 struct tcm_loop_nexus *tl_nexus;
1006 int ret = -ENOMEM; 990 int ret = -ENOMEM;
1007 991
1008 if (tl_tpg->tl_hba->tl_nexus) { 992 if (tl_tpg->tl_nexus) {
1009 pr_debug("tl_tpg->tl_hba->tl_nexus already exists\n"); 993 pr_debug("tl_tpg->tl_nexus already exists\n");
1010 return -EEXIST; 994 return -EEXIST;
1011 } 995 }
1012 se_tpg = &tl_tpg->tl_se_tpg; 996 se_tpg = &tl_tpg->tl_se_tpg;
@@ -1041,7 +1025,7 @@ static int tcm_loop_make_nexus(
1041 */ 1025 */
1042 __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, 1026 __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
1043 tl_nexus->se_sess, tl_nexus); 1027 tl_nexus->se_sess, tl_nexus);
1044 tl_tpg->tl_hba->tl_nexus = tl_nexus; 1028 tl_tpg->tl_nexus = tl_nexus;
1045 pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated" 1029 pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
1046 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), 1030 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
1047 name); 1031 name);
@@ -1057,12 +1041,8 @@ static int tcm_loop_drop_nexus(
1057{ 1041{
1058 struct se_session *se_sess; 1042 struct se_session *se_sess;
1059 struct tcm_loop_nexus *tl_nexus; 1043 struct tcm_loop_nexus *tl_nexus;
1060 struct tcm_loop_hba *tl_hba = tpg->tl_hba;
1061 1044
1062 if (!tl_hba) 1045 tl_nexus = tpg->tl_nexus;
1063 return -ENODEV;
1064
1065 tl_nexus = tl_hba->tl_nexus;
1066 if (!tl_nexus) 1046 if (!tl_nexus)
1067 return -ENODEV; 1047 return -ENODEV;
1068 1048
@@ -1078,13 +1058,13 @@ static int tcm_loop_drop_nexus(
1078 } 1058 }
1079 1059
1080 pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated" 1060 pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
1081 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba), 1061 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba),
1082 tl_nexus->se_sess->se_node_acl->initiatorname); 1062 tl_nexus->se_sess->se_node_acl->initiatorname);
1083 /* 1063 /*
1084 * Release the SCSI I_T Nexus to the emulated SAS Target Port 1064 * Release the SCSI I_T Nexus to the emulated SAS Target Port
1085 */ 1065 */
1086 transport_deregister_session(tl_nexus->se_sess); 1066 transport_deregister_session(tl_nexus->se_sess);
1087 tpg->tl_hba->tl_nexus = NULL; 1067 tpg->tl_nexus = NULL;
1088 kfree(tl_nexus); 1068 kfree(tl_nexus);
1089 return 0; 1069 return 0;
1090} 1070}
@@ -1100,7 +1080,7 @@ static ssize_t tcm_loop_tpg_show_nexus(
1100 struct tcm_loop_nexus *tl_nexus; 1080 struct tcm_loop_nexus *tl_nexus;
1101 ssize_t ret; 1081 ssize_t ret;
1102 1082
1103 tl_nexus = tl_tpg->tl_hba->tl_nexus; 1083 tl_nexus = tl_tpg->tl_nexus;
1104 if (!tl_nexus) 1084 if (!tl_nexus)
1105 return -ENODEV; 1085 return -ENODEV;
1106 1086
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h
index 54c59d0b6608..6ae49f272ba6 100644
--- a/drivers/target/loopback/tcm_loop.h
+++ b/drivers/target/loopback/tcm_loop.h
@@ -27,11 +27,6 @@ struct tcm_loop_tmr {
27}; 27};
28 28
29struct tcm_loop_nexus { 29struct tcm_loop_nexus {
30 int it_nexus_active;
31 /*
32 * Pointer to Linux/SCSI HBA from linux/include/scsi_host.h
33 */
34 struct scsi_host *sh;
35 /* 30 /*
36 * Pointer to TCM session for I_T Nexus 31 * Pointer to TCM session for I_T Nexus
37 */ 32 */
@@ -51,6 +46,7 @@ struct tcm_loop_tpg {
51 atomic_t tl_tpg_port_count; 46 atomic_t tl_tpg_port_count;
52 struct se_portal_group tl_se_tpg; 47 struct se_portal_group tl_se_tpg;
53 struct tcm_loop_hba *tl_hba; 48 struct tcm_loop_hba *tl_hba;
49 struct tcm_loop_nexus *tl_nexus;
54}; 50};
55 51
56struct tcm_loop_hba { 52struct tcm_loop_hba {
@@ -59,7 +55,6 @@ struct tcm_loop_hba {
59 struct se_hba_s *se_hba; 55 struct se_hba_s *se_hba;
60 struct se_lun *tl_hba_lun; 56 struct se_lun *tl_hba_lun;
61 struct se_port *tl_hba_lun_sep; 57 struct se_port *tl_hba_lun_sep;
62 struct tcm_loop_nexus *tl_nexus;
63 struct device dev; 58 struct device dev;
64 struct Scsi_Host *sh; 59 struct Scsi_Host *sh;
65 struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA]; 60 struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA];