Skip to content

Commit

Permalink
target: pass sense_reason as a return value
Browse files Browse the repository at this point in the history
Pass the sense reason as an explicit return value from the I/O submission
path instead of storing it in struct se_cmd and using negative return
values.  This cleans up a lot of the code pathes, and with the sparse
annotations for the new sense_reason_t type allows for much better
error checking.

(nab: Convert spc_emulate_modesense + spc_emulate_modeselect to use
      sense_reason_t with Roland's MODE SELECT changes)

Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Roland Dreier <roland@purestorage.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed Nov 7, 2012
1 parent fecae40 commit de103c9
Show file tree
Hide file tree
Showing 24 changed files with 841 additions and 1,059 deletions.
43 changes: 18 additions & 25 deletions drivers/infiniband/ulp/srpt/ib_srpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1730,7 +1730,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
uint64_t unpacked_lun;
u64 data_len;
enum dma_data_direction dir;
int ret;
sense_reason_t ret;

BUG_ON(!send_ioctx);

Expand All @@ -1755,12 +1755,10 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
break;
}

ret = srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len);
if (ret) {
if (srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len)) {
printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n",
srp_cmd->tag);
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
ret = TCM_INVALID_CDB_FIELD;
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
goto send_sense;
}
Expand All @@ -1769,26 +1767,26 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
cmd->data_direction = dir;
unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
sizeof(srp_cmd->lun));
if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) {
ret = transport_lookup_cmd_lun(cmd, unpacked_lun);
if (ret) {
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
goto send_sense;
}
ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb);
if (ret < 0) {
if (ret) {
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) {
if (ret == TCM_RESERVATION_CONFLICT) {
srpt_queue_status(cmd);
return 0;
} else
goto send_sense;
}
goto send_sense;
}

transport_handle_cdb_direct(cmd);
return 0;

send_sense:
transport_send_check_condition_and_sense(cmd, cmd->scsi_sense_reason,
0);
transport_send_check_condition_and_sense(cmd, ret, 0);
return -1;
}

Expand Down Expand Up @@ -1882,39 +1880,34 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
send_ioctx->tag = srp_tsk->tag;
tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);
if (tcm_tmr < 0) {
send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
send_ioctx->cmd.se_tmr_req->response =
TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
goto process_tmr;
goto fail;
}
res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
if (res < 0) {
send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
goto process_tmr;
goto fail;
}

unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,
sizeof(srp_tsk->lun));
res = transport_lookup_tmr_lun(&send_ioctx->cmd, unpacked_lun);
if (res) {
pr_debug("rejecting TMR for LUN %lld\n", unpacked_lun);
send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
send_ioctx->cmd.se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
goto process_tmr;
goto fail;
}

if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);

process_tmr:
kref_get(&send_ioctx->kref);
if (!(send_ioctx->cmd.se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
transport_generic_handle_tmr(&send_ioctx->cmd);
else
transport_send_check_condition_and_sense(cmd,
cmd->scsi_sense_reason, 0);

transport_generic_handle_tmr(&send_ioctx->cmd);
return;
fail:
kref_get(&send_ioctx->kref);
transport_send_check_condition_and_sense(cmd, 0, 0); // XXX:
}

/**
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/qla2xxx/tcm_qla2xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
return;
}

cmd->se_cmd.scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD;
transport_generic_request_failure(&cmd->se_cmd);
transport_generic_request_failure(&cmd->se_cmd,
TCM_CHECK_CONDITION_ABORT_CMD);
return;
}

Expand Down
80 changes: 28 additions & 52 deletions drivers/target/iscsi/iscsi_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,9 +767,8 @@ static int iscsit_handle_scsi_cmd(
struct iscsi_conn *conn,
unsigned char *buf)
{
int data_direction, cmdsn_ret = 0, immed_ret, ret, transport_ret;
int dump_immediate_data = 0, send_check_condition = 0, payload_length;
struct iscsi_cmd *cmd = NULL;
int data_direction, payload_length, cmdsn_ret = 0, immed_ret;
struct iscsi_cmd *cmd = NULL;
struct iscsi_scsi_req *hdr;
int iscsi_task_attr;
int sam_task_attr;
Expand Down Expand Up @@ -956,38 +955,26 @@ static int iscsit_handle_scsi_cmd(
" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
hdr->cmdsn, hdr->data_length, payload_length, conn->cid);

/*
* The CDB is going to an se_device_t.
*/
ret = transport_lookup_cmd_lun(&cmd->se_cmd,
scsilun_to_int(&hdr->lun));
if (ret < 0) {
if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) {
pr_debug("Responding to non-acl'ed,"
" non-existent or non-exported iSCSI LUN:"
" 0x%016Lx\n", get_unaligned_le64(&hdr->lun));
cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
scsilun_to_int(&hdr->lun));
if (cmd->sense_reason)
goto attach_cmd;

cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
if (cmd->sense_reason) {
if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
return iscsit_add_reject_from_cmd(
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 1, buf, cmd);
}
send_check_condition = 1;

goto attach_cmd;
}

transport_ret = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
if (transport_ret == -ENOMEM) {
if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
return iscsit_add_reject_from_cmd(
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 1, buf, cmd);
} else if (transport_ret < 0) {
/*
* Unsupported SAM Opcode. CHECK_CONDITION will be sent
* in iscsit_execute_cmd() during the CmdSN OOO Execution
* Mechinism.
*/
send_check_condition = 1;
} else {
if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0)
return iscsit_add_reject_from_cmd(
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 1, buf, cmd);
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 1, buf, cmd);
}

attach_cmd:
Expand All @@ -1000,11 +987,12 @@ static int iscsit_handle_scsi_cmd(
*/
core_alua_check_nonop_delay(&cmd->se_cmd);

ret = iscsit_allocate_iovecs(cmd);
if (ret < 0)
if (iscsit_allocate_iovecs(cmd) < 0) {
return iscsit_add_reject_from_cmd(
ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 0, buf, cmd);
}

/*
* Check the CmdSN against ExpCmdSN/MaxCmdSN here if
* the Immediate Bit is not set, and no Immediate
Expand All @@ -1031,10 +1019,7 @@ static int iscsit_handle_scsi_cmd(
* If no Immediate Data is attached, it's OK to return now.
*/
if (!cmd->immediate_data) {
if (send_check_condition)
return 0;

if (cmd->unsolicited_data) {
if (!cmd->sense_reason && cmd->unsolicited_data) {
iscsit_set_dataout_sequence_values(cmd);

spin_lock_bh(&cmd->dataout_timeout_lock);
Expand All @@ -1050,19 +1035,17 @@ static int iscsit_handle_scsi_cmd(
* thread. They are processed in CmdSN order by
* iscsit_check_received_cmdsn() below.
*/
if (send_check_condition) {
if (cmd->sense_reason) {
immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
dump_immediate_data = 1;
goto after_immediate_data;
}
/*
* Call directly into transport_generic_new_cmd() to perform
* the backend memory allocation.
*/
ret = transport_generic_new_cmd(&cmd->se_cmd);
if (ret < 0) {
cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
if (cmd->sense_reason) {
immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
dump_immediate_data = 1;
goto after_immediate_data;
}

Expand All @@ -1079,7 +1062,7 @@ static int iscsit_handle_scsi_cmd(
* Special case for Unsupported SAM WRITE Opcodes
* and ImmediateData=Yes.
*/
if (dump_immediate_data) {
if (cmd->sense_reason) {
if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
return -1;
} else if (cmd->unsolicited_data) {
Expand Down Expand Up @@ -1272,8 +1255,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);

spin_lock_irqsave(&se_cmd->t_state_lock, flags);
if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) ||
(se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE))
dump_unsolicited_data = 1;
spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);

Expand Down Expand Up @@ -1742,7 +1724,6 @@ static int iscsit_handle_task_mgt_cmd(
ret = transport_lookup_tmr_lun(&cmd->se_cmd,
scsilun_to_int(&hdr->lun));
if (ret < 0) {
cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
goto attach;
}
Expand All @@ -1751,10 +1732,8 @@ static int iscsit_handle_task_mgt_cmd(
switch (function) {
case ISCSI_TM_FUNC_ABORT_TASK:
se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) {
cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
if (se_tmr->response)
goto attach;
}
break;
case ISCSI_TM_FUNC_ABORT_TASK_SET:
case ISCSI_TM_FUNC_CLEAR_ACA:
Expand All @@ -1763,14 +1742,12 @@ static int iscsit_handle_task_mgt_cmd(
break;
case ISCSI_TM_FUNC_TARGET_WARM_RESET:
if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
goto attach;
}
break;
case ISCSI_TM_FUNC_TARGET_COLD_RESET:
if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
goto attach;
}
Expand All @@ -1781,7 +1758,7 @@ static int iscsit_handle_task_mgt_cmd(
* Perform sanity checks on the ExpDataSN only if the
* TASK_REASSIGN was successful.
*/
if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE)
if (se_tmr->response)
break;

if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
Expand All @@ -1792,7 +1769,6 @@ static int iscsit_handle_task_mgt_cmd(
default:
pr_err("Unknown TMR function: 0x%02x, protocol"
" error.\n", function);
cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
goto attach;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/target/iscsi/iscsi_target_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ struct iscsi_cmd {
struct scatterlist *first_data_sg;
u32 first_data_sg_off;
u32 kmapped_nents;

sense_reason_t sense_reason;
} ____cacheline_aligned;

struct iscsi_tmr_req {
Expand Down
11 changes: 5 additions & 6 deletions drivers/target/iscsi/iscsi_target_erl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -929,11 +929,10 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
case ISCSI_OP_SCSI_CMD:
/*
* Go ahead and send the CHECK_CONDITION status for
* any SCSI CDB exceptions that may have occurred, also
* handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
* any SCSI CDB exceptions that may have occurred.
*/
if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) {
if (cmd->sense_reason) {
if (cmd->sense_reason == TCM_RESERVATION_CONFLICT) {
cmd->i_state = ISTATE_SEND_STATUS;
spin_unlock_bh(&cmd->istate_lock);
iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
Expand All @@ -956,7 +955,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
* exception
*/
return transport_send_check_condition_and_sense(se_cmd,
se_cmd->scsi_sense_reason, 0);
cmd->sense_reason, 0);
}
/*
* Special case for delayed CmdSN with Immediate
Expand Down Expand Up @@ -1013,7 +1012,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
break;
case ISCSI_OP_SCSI_TMFUNC:
if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
if (cmd->se_cmd.se_tmr_req->response) {
spin_unlock_bh(&cmd->istate_lock);
iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
cmd->i_state);
Expand Down
Loading

0 comments on commit de103c9

Please sign in to comment.