Skip to content

Commit a656183

Browse files
gonzoleemanmartinkpetersen
authored andcommitted
scsi: libiscsi: Hold back_lock when calling iscsi_complete_task
If there is an error queueing an iscsi command in iscsi_queuecommand(), for example if the transport fails to take the command in sessuin->tt->xmit_task(), then the error path can call iscsi_complete_task() without first aquiring the back_lock as required. This can lead to things like ITT pool can get corrupt, resulting in duplicate ITTs being sent out. The solution is to hold the back_lock around iscsi_complete_task() calls, and to add a little commenting to help others understand when back_lock must be held. Signed-off-by: Lee Duncan <lduncan@suse.com> Acked-by: Chris Leech <cleech@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent cf9efd5 commit a656183

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

drivers/scsi/libiscsi.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
798798
* @datalen: len of buffer
799799
*
800800
* iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and
801-
* then completes the command and task.
801+
* then completes the command and task. called under back_lock
802802
**/
803803
static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
804804
struct iscsi_task *task, char *data,
@@ -894,6 +894,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
894894
* @conn: iscsi connection
895895
* @hdr: iscsi pdu
896896
* @task: scsi command task
897+
*
898+
* iscsi_data_in_rsp sets up the scsi_cmnd fields based on the data received
899+
* then completes the command and task. called under back_lock
897900
**/
898901
static void
899902
iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
@@ -978,6 +981,16 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
978981
return 0;
979982
}
980983

984+
/**
985+
* iscsi_nop_out_rsp - SCSI NOP Response processing
986+
* @task: scsi command task
987+
* @nop: the nop structure
988+
* @data: where to put the data
989+
* @datalen: length of data
990+
*
991+
* iscsi_nop_out_rsp handles nop response from use or
992+
* from user space. called under back_lock
993+
**/
981994
static int iscsi_nop_out_rsp(struct iscsi_task *task,
982995
struct iscsi_nopin *nop, char *data, int datalen)
983996
{
@@ -1744,15 +1757,19 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
17441757
return 0;
17451758

17461759
prepd_reject:
1760+
spin_lock_bh(&session->back_lock);
17471761
iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
1762+
spin_unlock_bh(&session->back_lock);
17481763
reject:
17491764
spin_unlock_bh(&session->frwd_lock);
17501765
ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
17511766
sc->cmnd[0], reason);
17521767
return SCSI_MLQUEUE_TARGET_BUSY;
17531768

17541769
prepd_fault:
1770+
spin_lock_bh(&session->back_lock);
17551771
iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
1772+
spin_unlock_bh(&session->back_lock);
17561773
fault:
17571774
spin_unlock_bh(&session->frwd_lock);
17581775
ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
@@ -3069,8 +3086,9 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn)
30693086
state = ISCSI_TASK_ABRT_SESS_RECOV;
30703087
if (task->state == ISCSI_TASK_PENDING)
30713088
state = ISCSI_TASK_COMPLETED;
3089+
spin_lock_bh(&session->back_lock);
30723090
iscsi_complete_task(task, state);
3073-
3091+
spin_unlock_bh(&session->back_lock);
30743092
}
30753093
}
30763094

0 commit comments

Comments
 (0)