Commit ba159914 authored by Nicholas Bellinger's avatar Nicholas Bellinger

iscsi-target: Fix iscsit_add_reject* usage for iser

This patch changes iscsit_add_reject() + iscsit_add_reject_from_cmd()
usage to not sleep on iscsi_cmd->reject_comp to address a free-after-use
usage bug in v3.10 with iser-target code.

It saves ->reject_reason for use within iscsit_build_reject() so the
correct value for both transport cases.  It also drops the legacy
fail_conn parameter usage throughput iscsi-target code and adds
two iscsit_add_reject_cmd() and iscsit_reject_cmd helper functions,
along with various small cleanups.

(v2: Re-enable target_put_sess_cmd() to be called from
     iscsit_add_reject_from_cmd() for rejects invoked after
     target_get_sess_cmd() has been called)

Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Mike Christie <michaelc@cs.wisc.edu>
Cc: stable@vger.kernel.org  # 3.10+
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 3df8f68a
...@@ -939,11 +939,6 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn, ...@@ -939,11 +939,6 @@ isert_handle_scsi_cmd(struct isert_conn *isert_conn,
if (!rc && dump_payload == false && unsol_data) if (!rc && dump_payload == false && unsol_data)
iscsit_set_unsoliticed_dataout(cmd); iscsit_set_unsoliticed_dataout(cmd);
if (rc == CMDSN_ERROR_CANNOT_RECOVER)
return iscsit_add_reject_from_cmd(
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, (unsigned char *)hdr, cmd);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, ...@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *,
extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
struct iscsi_portal_group *); struct iscsi_portal_group *);
extern int iscsit_del_np(struct iscsi_np *); extern int iscsit_del_np(struct iscsi_np *);
extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *); extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *);
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
......
...@@ -132,9 +132,8 @@ enum cmd_flags_table { ...@@ -132,9 +132,8 @@ enum cmd_flags_table {
ICF_CONTIG_MEMORY = 0x00000020, ICF_CONTIG_MEMORY = 0x00000020,
ICF_ATTACHED_TO_RQUEUE = 0x00000040, ICF_ATTACHED_TO_RQUEUE = 0x00000040,
ICF_OOO_CMDSN = 0x00000080, ICF_OOO_CMDSN = 0x00000080,
ICF_REJECT_FAIL_CONN = 0x00000100, IFC_SENDTARGETS_ALL = 0x00000100,
IFC_SENDTARGETS_ALL = 0x00000200, IFC_SENDTARGETS_SINGLE = 0x00000200,
IFC_SENDTARGETS_SINGLE = 0x00000400,
}; };
/* struct iscsi_cmd->i_state */ /* struct iscsi_cmd->i_state */
...@@ -368,6 +367,8 @@ struct iscsi_cmd { ...@@ -368,6 +367,8 @@ struct iscsi_cmd {
u8 maxcmdsn_inc; u8 maxcmdsn_inc;
/* Immediate Unsolicited Dataout */ /* Immediate Unsolicited Dataout */
u8 unsolicited_data; u8 unsolicited_data;
/* Reject reason code */
u8 reject_reason;
/* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */ /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */
u16 logout_cid; u16 logout_cid;
/* Command flags */ /* Command flags */
...@@ -450,7 +451,6 @@ struct iscsi_cmd { ...@@ -450,7 +451,6 @@ struct iscsi_cmd {
struct list_head datain_list; struct list_head datain_list;
/* R2T List */ /* R2T List */
struct list_head cmd_r2t_list; struct list_head cmd_r2t_list;
struct completion reject_comp;
/* Timer for DataOUT */ /* Timer for DataOUT */
struct timer_list dataout_timer; struct timer_list dataout_timer;
/* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */
......
...@@ -746,13 +746,12 @@ int iscsit_check_post_dataout( ...@@ -746,13 +746,12 @@ int iscsit_check_post_dataout(
if (!conn->sess->sess_ops->ErrorRecoveryLevel) { if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
pr_err("Unable to recover from DataOUT CRC" pr_err("Unable to recover from DataOUT CRC"
" failure while ERL=0, closing session.\n"); " failure while ERL=0, closing session.\n");
iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR,
1, 0, buf, cmd); buf);
return DATAOUT_CANNOT_RECOVER; return DATAOUT_CANNOT_RECOVER;
} }
iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR, iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf);
0, 0, buf, cmd);
return iscsit_dataout_post_crc_failed(cmd, buf); return iscsit_dataout_post_crc_failed(cmd, buf);
} }
} }
......
...@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack( ...@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack(
" protocol error.\n", cmd->init_task_tag, begrun, " protocol error.\n", cmd->init_task_tag, begrun,
(begrun + runlength), cmd->acked_data_sn); (begrun + runlength), cmd->acked_data_sn);
return iscsit_add_reject_from_cmd( return iscsit_reject_cmd(cmd,
ISCSI_REASON_PROTOCOL_ERROR, ISCSI_REASON_PROTOCOL_ERROR, buf);
1, 0, buf, cmd);
} }
if (runlength) { if (runlength) {
...@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack( ...@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack(
" with BegRun: 0x%08x, RunLength: 0x%08x, exceeds" " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds"
" current R2TSN: 0x%08x, protocol error.\n", " current R2TSN: 0x%08x, protocol error.\n",
cmd->init_task_tag, begrun, runlength, cmd->r2t_sn); cmd->init_task_tag, begrun, runlength, cmd->r2t_sn);
return iscsit_add_reject_from_cmd( return iscsit_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd); ISCSI_REASON_BOOKMARK_INVALID, buf);
} }
last_r2tsn = (begrun + runlength); last_r2tsn = (begrun + runlength);
} else } else
...@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain( ...@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain(
" protocol error.\n", cmd->init_task_tag, begrun, " protocol error.\n", cmd->init_task_tag, begrun,
(begrun + runlength), cmd->acked_data_sn); (begrun + runlength), cmd->acked_data_sn);
return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR, return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
1, 0, buf, cmd);
} }
/* /*
...@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain( ...@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain(
pr_err("Initiator requesting BegRun: 0x%08x, RunLength" pr_err("Initiator requesting BegRun: 0x%08x, RunLength"
": 0x%08x greater than maximum DataSN: 0x%08x.\n", ": 0x%08x greater than maximum DataSN: 0x%08x.\n",
begrun, runlength, (cmd->data_sn - 1)); begrun, runlength, (cmd->data_sn - 1));
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID, return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID,
1, 0, buf, cmd); buf);
} }
dr = iscsit_allocate_datain_req(); dr = iscsit_allocate_datain_req();
if (!dr) if (!dr)
return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_NO_RESOURCES, return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1, 0, buf, cmd); buf);
dr->data_sn = dr->begrun = begrun; dr->data_sn = dr->begrun = begrun;
dr->runlength = runlength; dr->runlength = runlength;
......
...@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask) ...@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
INIT_LIST_HEAD(&cmd->i_conn_node); INIT_LIST_HEAD(&cmd->i_conn_node);
INIT_LIST_HEAD(&cmd->datain_list); INIT_LIST_HEAD(&cmd->datain_list);
INIT_LIST_HEAD(&cmd->cmd_r2t_list); INIT_LIST_HEAD(&cmd->cmd_r2t_list);
init_completion(&cmd->reject_comp);
spin_lock_init(&cmd->datain_lock); spin_lock_init(&cmd->datain_lock);
spin_lock_init(&cmd->dataout_timeout_lock); spin_lock_init(&cmd->dataout_timeout_lock);
spin_lock_init(&cmd->istate_lock); spin_lock_init(&cmd->istate_lock);
......
...@@ -34,8 +34,6 @@ extern void iscsit_put_transport(struct iscsit_transport *); ...@@ -34,8 +34,6 @@ extern void iscsit_put_transport(struct iscsit_transport *);
/* /*
* From iscsi_target.c * From iscsi_target.c
*/ */
extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *,
struct iscsi_cmd *);
extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *,
unsigned char *); unsigned char *);
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); extern void iscsit_set_unsoliticed_dataout(struct iscsi_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