diff options
author | Roland Dreier <roland@purestorage.com> | 2012-07-16 14:04:39 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-07-17 20:05:05 -0400 |
commit | d6dfc868bcf329392abd1ecfa7357eb51ebf8c30 (patch) | |
tree | 7eb33785e4d6a59111560b56e68f4facaddee310 /drivers | |
parent | 7409a6657aebf8be74c21d0eded80709b27275cb (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.c | 3 | ||||
-rw-r--r-- | drivers/target/sbp/sbp_target.c | 8 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 14 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tfc_cmd.c | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/tcm_usb_gadget.c | 36 |
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 | ||
606 | static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | 605 | static 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 | ||
1243 | err: | 1245 | err: |
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 | **/ |
1453 | void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, | 1457 | int 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 | } |
1512 | EXPORT_SYMBOL(target_submit_cmd); | 1516 | EXPORT_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 | |||
1078 | out: | ||
1079 | transport_send_check_condition_and_sense(se_cmd, | ||
1080 | TCM_UNSUPPORTED_SCSI_OPCODE, 1); | ||
1081 | usbg_cleanup_cmd(cmd); | ||
1078 | } | 1082 | } |
1079 | 1083 | ||
1080 | static int usbg_submit_command(struct f_uas *fu, | 1084 | static 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 | |||
1194 | out: | ||
1195 | transport_send_check_condition_and_sense(se_cmd, | ||
1196 | TCM_UNSUPPORTED_SCSI_OPCODE, 1); | ||
1197 | usbg_cleanup_cmd(cmd); | ||
1190 | } | 1198 | } |
1191 | 1199 | ||
1192 | static int bot_submit_command(struct f_uas *fu, | 1200 | static int bot_submit_command(struct f_uas *fu, |