aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2012-07-16 14:04:39 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-07-17 20:05:05 -0400
commitd6dfc868bcf329392abd1ecfa7357eb51ebf8c30 (patch)
tree7eb33785e4d6a59111560b56e68f4facaddee310 /drivers
parent7409a6657aebf8be74c21d0eded80709b27275cb (diff)
target: Allow for target_submit_cmd() returning errors
We want it to be possible for target_submit_cmd() to return errors up to its fabric module callers. For now just update the prototype to return an int, and update all callers to handle non-zero return values as an error. This is immediately useful for tcm_qla2xxx to fix a long-standing active I/O session shutdown race, but tcm_fc, usb-gadget, and sbp-target the fabric maintainers need to check + ACK that handling a target_submit_cmd() failure due to session shutdown does not introduce regressions (nab: Respin against for-next after initial NACK + update docbook comment + fix double se_cmd init in exception path for usb-gadget) Cc: Chad Dupuis <chad.dupuis@qlogic.com> Cc: Arun Easi <arun.easi@qlogic.com> Cc: Chris Boot <bootc@bootc.net> Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> Cc: Mark Rustad <mark.d.rustad@intel.com> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Felipe Balbi <balbi@ti.com> Cc: Andy Grover <agrover@redhat.com> Signed-off-by: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c3
-rw-r--r--drivers/target/sbp/sbp_target.c8
-rw-r--r--drivers/target/target_core_transport.c14
-rw-r--r--drivers/target/tcm_fc/tfc_cmd.c8
-rw-r--r--drivers/usb/gadget/tcm_usb_gadget.c36
5 files changed, 42 insertions, 27 deletions
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 65a7ed9ac81d..4752f65a9272 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -597,10 +597,9 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
597 return -EINVAL; 597 return -EINVAL;
598 } 598 }
599 599
600 target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0], 600 return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
601 cmd->unpacked_lun, data_length, fcp_task_attr, 601 cmd->unpacked_lun, data_length, fcp_task_attr,
602 data_dir, flags); 602 data_dir, flags);
603 return 0;
604} 603}
605 604
606static void tcm_qla2xxx_handle_data_work(struct work_struct *work) 605static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index e10e6223e96c..39ddba584b30 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -1235,9 +1235,11 @@ static void sbp_handle_command(struct sbp_target_request *req)
1235 pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n", 1235 pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n",
1236 req->orb_pointer, unpacked_lun, data_length, data_dir); 1236 req->orb_pointer, unpacked_lun, data_length, data_dir);
1237 1237
1238 target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, 1238 if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf,
1239 req->sense_buf, unpacked_lun, data_length, 1239 req->sense_buf, unpacked_lun, data_length,
1240 MSG_SIMPLE_TAG, data_dir, 0); 1240 MSG_SIMPLE_TAG, data_dir, 0))
1241 goto err;
1242
1241 return; 1243 return;
1242 1244
1243err: 1245err:
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 14e54b48fb8c..7647ecafbcc7 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1447,10 +1447,14 @@ EXPORT_SYMBOL(transport_handle_cdb_direct);
1447 * @data_dir: DMA data direction 1447 * @data_dir: DMA data direction
1448 * @flags: flags for command submission from target_sc_flags_tables 1448 * @flags: flags for command submission from target_sc_flags_tables
1449 * 1449 *
1450 * Returns non zero to signal active I/O shutdown failure. All other
1451 * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
1452 * but still return zero here.
1453 *
1450 * This may only be called from process context, and also currently 1454 * This may only be called from process context, and also currently
1451 * assumes internal allocation of fabric payload buffer by target-core. 1455 * assumes internal allocation of fabric payload buffer by target-core.
1452 **/ 1456 **/
1453void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, 1457int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
1454 unsigned char *cdb, unsigned char *sense, u32 unpacked_lun, 1458 unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
1455 u32 data_length, int task_attr, int data_dir, int flags) 1459 u32 data_length, int task_attr, int data_dir, int flags)
1456{ 1460{
@@ -1478,7 +1482,7 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
1478 */ 1482 */
1479 rc = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF)); 1483 rc = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
1480 if (rc) 1484 if (rc)
1481 return; 1485 return rc;
1482 /* 1486 /*
1483 * Signal bidirectional data payloads to target-core 1487 * Signal bidirectional data payloads to target-core
1484 */ 1488 */
@@ -1491,13 +1495,13 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
1491 transport_send_check_condition_and_sense(se_cmd, 1495 transport_send_check_condition_and_sense(se_cmd,
1492 se_cmd->scsi_sense_reason, 0); 1496 se_cmd->scsi_sense_reason, 0);
1493 target_put_sess_cmd(se_sess, se_cmd); 1497 target_put_sess_cmd(se_sess, se_cmd);
1494 return; 1498 return 0;
1495 } 1499 }
1496 1500
1497 rc = target_setup_cmd_from_cdb(se_cmd, cdb); 1501 rc = target_setup_cmd_from_cdb(se_cmd, cdb);
1498 if (rc != 0) { 1502 if (rc != 0) {
1499 transport_generic_request_failure(se_cmd); 1503 transport_generic_request_failure(se_cmd);
1500 return; 1504 return 0;
1501 } 1505 }
1502 1506
1503 /* 1507 /*
@@ -1507,7 +1511,7 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
1507 core_alua_check_nonop_delay(se_cmd); 1511 core_alua_check_nonop_delay(se_cmd);
1508 1512
1509 transport_handle_cdb_direct(se_cmd); 1513 transport_handle_cdb_direct(se_cmd);
1510 return; 1514 return 0;
1511} 1515}
1512EXPORT_SYMBOL(target_submit_cmd); 1516EXPORT_SYMBOL(target_submit_cmd);
1513 1517
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 4ad58ac823e5..b9cb5006177e 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -543,9 +543,11 @@ static void ft_send_work(struct work_struct *work)
543 * Use a single se_cmd->cmd_kref as we expect to release se_cmd 543 * Use a single se_cmd->cmd_kref as we expect to release se_cmd
544 * directly from ft_check_stop_free callback in response path. 544 * directly from ft_check_stop_free callback in response path.
545 */ 545 */
546 target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb, 546 if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb,
547 &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun), 547 &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
548 ntohl(fcp->fc_dl), task_attr, data_dir, 0); 548 ntohl(fcp->fc_dl), task_attr, data_dir, 0))
549 goto err;
550
549 pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl); 551 pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl);
550 return; 552 return;
551 553
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c
index 02ace18fca0b..5444866e13ef 100644
--- a/drivers/usb/gadget/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/tcm_usb_gadget.c
@@ -1065,16 +1065,20 @@ static void usbg_cmd_work(struct work_struct *work)
1065 tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, 1065 tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
1066 tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, 1066 tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
1067 cmd->prio_attr, cmd->sense_iu.sense); 1067 cmd->prio_attr, cmd->sense_iu.sense);
1068 1068 goto out;
1069 transport_send_check_condition_and_sense(se_cmd,
1070 TCM_UNSUPPORTED_SCSI_OPCODE, 1);
1071 usbg_cleanup_cmd(cmd);
1072 return;
1073 } 1069 }
1074 1070
1075 target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, 1071 if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
1076 cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, 1072 cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
1077 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE); 1073 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE) < 0)
1074 goto out;
1075
1076 return;
1077
1078out:
1079 transport_send_check_condition_and_sense(se_cmd,
1080 TCM_UNSUPPORTED_SCSI_OPCODE, 1);
1081 usbg_cleanup_cmd(cmd);
1078} 1082}
1079 1083
1080static int usbg_submit_command(struct f_uas *fu, 1084static int usbg_submit_command(struct f_uas *fu,
@@ -1177,16 +1181,20 @@ static void bot_cmd_work(struct work_struct *work)
1177 tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, 1181 tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
1178 tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, 1182 tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
1179 cmd->prio_attr, cmd->sense_iu.sense); 1183 cmd->prio_attr, cmd->sense_iu.sense);
1180 1184 goto out;
1181 transport_send_check_condition_and_sense(se_cmd,
1182 TCM_UNSUPPORTED_SCSI_OPCODE, 1);
1183 usbg_cleanup_cmd(cmd);
1184 return;
1185 } 1185 }
1186 1186
1187 target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, 1187 if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
1188 cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, 1188 cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
1189 cmd->data_len, cmd->prio_attr, dir, 0); 1189 cmd->data_len, cmd->prio_attr, dir, 0) < 0)
1190 goto out;
1191
1192 return;
1193
1194out:
1195 transport_send_check_condition_and_sense(se_cmd,
1196 TCM_UNSUPPORTED_SCSI_OPCODE, 1);
1197 usbg_cleanup_cmd(cmd);
1190} 1198}
1191 1199
1192static int bot_submit_command(struct f_uas *fu, 1200static int bot_submit_command(struct f_uas *fu,