scsi: target: Make the session shutdown code also wait for commands that are being aborted

Target drivers must call target_sess_cmd_list_set_waiting() and
target_wait_for_sess_cmds() before freeing a session. Since freeing a
session is only safe after all commands that are associated with a session
have finished, make target_wait_for_sess_cmds() also wait for commands that
are being aborted. Instead of setting a flag in each pending command from
target_sess_cmd_list_set_waiting() and waiting in
target_wait_for_sess_cmds() on a per-command completion, only set a
per-session flag in the former function and wait on a per-session
completion in the latter function. This change is safe because once a SCSI
initiator system has submitted a command a target system is always allowed
to execute it to completion. See also commit 0f4a943168 ("target: Fix
remote-port TMR ABORT + se_cmd fabric stop").

This patch is based on the following two patches:

* Bart Van Assche, target: Simplify session shutdown code, February 19, 2015
  (8df5463d7d).

* Christoph Hellwig, target: Rework session shutdown code, December 7, 2015
  (http://thread.gmane.org/gmane.linux.scsi.target.devel/10695).

Signed-off-by: Bart Van Assche <[email protected]>
Reviewed-by: Mike Christie <[email protected]>
Cc: Hannes Reinecke <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
This commit is contained in:
Bart Van Assche 2018-06-22 14:52:53 -07:00 • committed by Martin K. Petersen
commit 00d909a107
3 changed files with 24 additions and 61 deletions

View file

@ -443,7 +443,6 @@ struct se_cmd {
u8 scsi_asc;
u8 scsi_ascq;
u16 scsi_sense_length;
unsigned cmd_wait_set:1;
unsigned unknown_data_length:1;
bool state_active:1;
u64 tag; /* SAM command identifier aka task tag */
@ -606,8 +605,8 @@ struct se_session {
struct list_head sess_list;
struct list_head sess_acl_list;
struct list_head sess_cmd_list;
struct list_head sess_wait_list;
spinlock_t sess_cmd_lock;
wait_queue_head_t cmd_list_wq;
void *sess_cmd_map;
struct sbitmap_queue sess_tag_pool;
};