aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-07-03 06:11:48 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-04 04:50:34 -0400
commitc6ccbb9b6e24e35d71fd8706dfc5a8eab07f6937 (patch)
tree8ca00d0d33adf2cb6e683fa179d1473b5524bb2d
parentd9e507c05ca19ad2ec166577edd8b47e17c8961e (diff)
iscsi-target: Fix ISCSI_OP_SCSI_TMFUNC handling for iser
commit 186a9647019587b3784694894c4d136fd00cfd7b upstream. This patch adds target_get_sess_cmd reference counting for iscsit_handle_task_mgt_cmd(), and adds a target_put_sess_cmd() for the failure case. It also fixes a bug where ISCSI_OP_SCSI_TMFUNC type commands where leaking iscsi_cmd->i_conn_node and eventually triggering an OOPs during struct isert_conn shutdown. Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c16
-rw-r--r--drivers/target/iscsi/iscsi_target.c12
2 files changed, 18 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 6b20a9d09cbb..bfc21798bd5e 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -1202,14 +1202,12 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1202{ 1202{
1203 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; 1203 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
1204 struct isert_conn *isert_conn = isert_cmd->conn; 1204 struct isert_conn *isert_conn = isert_cmd->conn;
1205 struct iscsi_conn *conn; 1205 struct iscsi_conn *conn = isert_conn->conn;
1206 1206
1207 pr_debug("Entering isert_put_cmd: %p\n", isert_cmd); 1207 pr_debug("Entering isert_put_cmd: %p\n", isert_cmd);
1208 1208
1209 switch (cmd->iscsi_opcode) { 1209 switch (cmd->iscsi_opcode) {
1210 case ISCSI_OP_SCSI_CMD: 1210 case ISCSI_OP_SCSI_CMD:
1211 conn = isert_conn->conn;
1212
1213 spin_lock_bh(&conn->cmd_lock); 1211 spin_lock_bh(&conn->cmd_lock);
1214 if (!list_empty(&cmd->i_conn_node)) 1212 if (!list_empty(&cmd->i_conn_node))
1215 list_del(&cmd->i_conn_node); 1213 list_del(&cmd->i_conn_node);
@@ -1219,16 +1217,18 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1219 iscsit_stop_dataout_timer(cmd); 1217 iscsit_stop_dataout_timer(cmd);
1220 1218
1221 isert_unmap_cmd(isert_cmd, isert_conn); 1219 isert_unmap_cmd(isert_cmd, isert_conn);
1222 /* 1220 transport_generic_free_cmd(&cmd->se_cmd, 0);
1223 * Fall-through 1221 break;
1224 */
1225 case ISCSI_OP_SCSI_TMFUNC: 1222 case ISCSI_OP_SCSI_TMFUNC:
1223 spin_lock_bh(&conn->cmd_lock);
1224 if (!list_empty(&cmd->i_conn_node))
1225 list_del(&cmd->i_conn_node);
1226 spin_unlock_bh(&conn->cmd_lock);
1227
1226 transport_generic_free_cmd(&cmd->se_cmd, 0); 1228 transport_generic_free_cmd(&cmd->se_cmd, 0);
1227 break; 1229 break;
1228 case ISCSI_OP_REJECT: 1230 case ISCSI_OP_REJECT:
1229 case ISCSI_OP_NOOP_OUT: 1231 case ISCSI_OP_NOOP_OUT:
1230 conn = isert_conn->conn;
1231
1232 spin_lock_bh(&conn->cmd_lock); 1232 spin_lock_bh(&conn->cmd_lock);
1233 if (!list_empty(&cmd->i_conn_node)) 1233 if (!list_empty(&cmd->i_conn_node))
1234 list_del(&cmd->i_conn_node); 1234 list_del(&cmd->i_conn_node);
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index d7705e5824fb..f1db6ee71006 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1757,8 +1757,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1757 struct se_tmr_req *se_tmr; 1757 struct se_tmr_req *se_tmr;
1758 struct iscsi_tmr_req *tmr_req; 1758 struct iscsi_tmr_req *tmr_req;
1759 struct iscsi_tm *hdr; 1759 struct iscsi_tm *hdr;
1760 int out_of_order_cmdsn = 0; 1760 int out_of_order_cmdsn = 0, ret;
1761 int ret; 1761 bool sess_ref = false;
1762 u8 function; 1762 u8 function;
1763 1763
1764 hdr = (struct iscsi_tm *) buf; 1764 hdr = (struct iscsi_tm *) buf;
@@ -1814,6 +1814,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1814 conn->sess->se_sess, 0, DMA_NONE, 1814 conn->sess->se_sess, 0, DMA_NONE,
1815 MSG_SIMPLE_TAG, cmd->sense_buffer + 2); 1815 MSG_SIMPLE_TAG, cmd->sense_buffer + 2);
1816 1816
1817 target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
1818 sess_ref = true;
1819
1817 switch (function) { 1820 switch (function) {
1818 case ISCSI_TM_FUNC_ABORT_TASK: 1821 case ISCSI_TM_FUNC_ABORT_TASK:
1819 tcm_function = TMR_ABORT_TASK; 1822 tcm_function = TMR_ABORT_TASK;
@@ -1956,6 +1959,11 @@ attach:
1956 * For connection recovery, this is also the default action for 1959 * For connection recovery, this is also the default action for
1957 * TMR TASK_REASSIGN. 1960 * TMR TASK_REASSIGN.
1958 */ 1961 */
1962 if (sess_ref) {
1963 pr_debug("Handle TMR, using sess_ref=true check\n");
1964 target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
1965 }
1966
1959 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 1967 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
1960 return 0; 1968 return 0;
1961} 1969}