Commit 61db9527 authored by Kiran Patil's avatar Kiran Patil Committed by Nicholas Bellinger

tcm_fc: Fix ft_send_tm LUN lookup OOPs

This patch fixes a bug in ft_send_tm() that was incorrectly calling
ft_get_lun_for_cmd() -> transport_get_lun_for_cmd(), instead of using
transport_get_lun_for_tmr() for the proper struct se_lun lookup
that was triggering an OOPs in the se_cmd->tmr_req failure path.

This patch fixes the issue by re-arranging the codepath where
transport_get_lun_for_tmr() is called after tmr request is allocated and
made it available as part of se_cmd.

It also drops the now unnecessary ft_get_lun_for_cmd() unpacking code, and
uses scsilun_to_int() directly ahead of transport_get_lun_for_cmd() and
transport_get_lun_for_tmr() usage.
Signed-off-by: default avatarPatil, Kiran <kiran.patil@intel.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
Signed-off-by: default avatarNicholas A. Bellinger <nab@linux-iscsi.org>
parent 60d645a4
...@@ -144,7 +144,7 @@ enum ft_cmd_state { ...@@ -144,7 +144,7 @@ enum ft_cmd_state {
*/ */
struct ft_cmd { struct ft_cmd {
enum ft_cmd_state state; enum ft_cmd_state state;
u16 lun; /* LUN from request */ u32 lun; /* LUN from request */
struct ft_sess *sess; /* session held for cmd */ struct ft_sess *sess; /* session held for cmd */
struct fc_seq *seq; /* sequence in exchange mgr */ struct fc_seq *seq; /* sequence in exchange mgr */
struct se_cmd se_cmd; /* Local TCM I/O descriptor */ struct se_cmd se_cmd; /* Local TCM I/O descriptor */
......
...@@ -94,29 +94,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) ...@@ -94,29 +94,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0); 16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0);
} }
/*
* Get LUN from CDB.
*/
static int ft_get_lun_for_cmd(struct ft_cmd *cmd, u8 *lunp)
{
u64 lun;
lun = lunp[1];
switch (lunp[0] >> 6) {
case 0:
break;
case 1:
lun |= (lunp[0] & 0x3f) << 8;
break;
default:
return -1;
}
if (lun >= TRANSPORT_MAX_LUNS_PER_TPG)
return -1;
cmd->lun = lun;
return transport_get_lun_for_cmd(&cmd->se_cmd, NULL, lun);
}
static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd) static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd)
{ {
struct se_queue_obj *qobj; struct se_queue_obj *qobj;
...@@ -418,6 +395,7 @@ static void ft_send_tm(struct ft_cmd *cmd) ...@@ -418,6 +395,7 @@ static void ft_send_tm(struct ft_cmd *cmd)
{ {
struct se_tmr_req *tmr; struct se_tmr_req *tmr;
struct fcp_cmnd *fcp; struct fcp_cmnd *fcp;
struct ft_sess *sess;
u8 tm_func; u8 tm_func;
fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
...@@ -425,13 +403,6 @@ static void ft_send_tm(struct ft_cmd *cmd) ...@@ -425,13 +403,6 @@ static void ft_send_tm(struct ft_cmd *cmd)
switch (fcp->fc_tm_flags) { switch (fcp->fc_tm_flags) {
case FCP_TMF_LUN_RESET: case FCP_TMF_LUN_RESET:
tm_func = TMR_LUN_RESET; tm_func = TMR_LUN_RESET;
if (ft_get_lun_for_cmd(cmd, fcp->fc_lun) < 0) {
ft_dump_cmd(cmd, __func__);
transport_send_check_condition_and_sense(&cmd->se_cmd,
cmd->se_cmd.scsi_sense_reason, 0);
ft_sess_put(cmd->sess);
return;
}
break; break;
case FCP_TMF_TGT_RESET: case FCP_TMF_TGT_RESET:
tm_func = TMR_TARGET_WARM_RESET; tm_func = TMR_TARGET_WARM_RESET;
...@@ -463,6 +434,36 @@ static void ft_send_tm(struct ft_cmd *cmd) ...@@ -463,6 +434,36 @@ static void ft_send_tm(struct ft_cmd *cmd)
return; return;
} }
cmd->se_cmd.se_tmr_req = tmr; cmd->se_cmd.se_tmr_req = tmr;
switch (fcp->fc_tm_flags) {
case FCP_TMF_LUN_RESET:
cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
if (transport_get_lun_for_tmr(&cmd->se_cmd, cmd->lun) < 0) {
/*
* Make sure to clean up newly allocated TMR request
* since "unable to handle TMR request because failed
* to get to LUN"
*/
FT_TM_DBG("Failed to get LUN for TMR func %d, "
"se_cmd %p, unpacked_lun %d\n",
tm_func, &cmd->se_cmd, cmd->lun);
ft_dump_cmd(cmd, __func__);
sess = cmd->sess;
transport_send_check_condition_and_sense(&cmd->se_cmd,
cmd->se_cmd.scsi_sense_reason, 0);
transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
ft_sess_put(sess);
return;
}
break;
case FCP_TMF_TGT_RESET:
case FCP_TMF_CLR_TASK_SET:
case FCP_TMF_ABT_TASK_SET:
case FCP_TMF_CLR_ACA:
break;
default:
return;
}
transport_generic_handle_tmr(&cmd->se_cmd); transport_generic_handle_tmr(&cmd->se_cmd);
} }
...@@ -635,7 +636,8 @@ static void ft_send_cmd(struct ft_cmd *cmd) ...@@ -635,7 +636,8 @@ static void ft_send_cmd(struct ft_cmd *cmd)
fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd); fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
ret = ft_get_lun_for_cmd(cmd, fcp->fc_lun); cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
ret = transport_get_lun_for_cmd(&cmd->se_cmd, NULL, cmd->lun);
if (ret < 0) { if (ret < 0) {
ft_dump_cmd(cmd, __func__); ft_dump_cmd(cmd, __func__);
transport_send_check_condition_and_sense(&cmd->se_cmd, transport_send_check_condition_and_sense(&cmd->se_cmd,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment