Commit e627c615 authored by Roland Dreier's avatar Roland Dreier Committed by Nicholas Bellinger

target: Fix missing CMD_T_ACTIVE bit regression for pending WRITEs

This patch fixes a regression bug introduced during v3.6.x code with
the following commit to drop transport_add_cmd_to_queue(), which
originally re-set CMD_T_ACTIVE during pending WRITE I/O submission:

commit af877292
Author: Christoph Hellwig <hch@infradead.org>
Date:   Sun Jul 8 15:58:49 2012 -0400

    target: replace the processing thread with a TMR work queue

The following sequence happens for write commands (or any other
commands with a data out phase):

 - The transport calls target_submit_cmd(), which sets CMD_T_ACTIVE in
   cmd->transport_state and sets cmd->t_state to TRANSPORT_NEW_CMD.
 - Things go on transport_generic_new_cmd(), which notices that the
   command needs to transfer data, so it sets cmd->t_state to
   TRANSPORT_WRITE_PENDING and calls transport_cmd_check_stop().
 - transport_cmd_check_stop() clears CMD_T_ACTIVE in cmd->transport_state
   and returns in the normal case.
 - Then we continue on to call ->se_tfo->write_pending().
 - The data comes back from the initiator, and the transport calls
   target_execute_cmd(), which sets cmd->t_state to TRANSPORT_PROCESSING
   and calls into the backend to actually write the data.

At this point, the backend might take a long time to complete the
command, since it has to do real IO.  If an abort request comes in for
this command at this point, it will not wait for the command to finish
since CMD_T_ACTIVE is not set.  Then when the command does finally
finish, we blow up with use-after-free.

Avoid this by setting CMD_T_ACTIVE in target_execute_cmd() so that
transport_wait_for_tasks() waits for the command to finish executing.
This matches the behavior from before commit 1389533e ("target:
remove transport_generic_handle_data"), when data was signaled via
transport_generic_handle_data(), which set CMD_T_ACTIVE because it
called transport_add_cmd_to_queue().
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
Reported-by: default avatarMartin Svec <martin.svec@zoner.cz>
Cc: Christoph Hellwig <hch@lst.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent edec8dfe
...@@ -1688,6 +1688,7 @@ void target_execute_cmd(struct se_cmd *cmd) ...@@ -1688,6 +1688,7 @@ void target_execute_cmd(struct se_cmd *cmd)
} }
cmd->t_state = TRANSPORT_PROCESSING; cmd->t_state = TRANSPORT_PROCESSING;
cmd->transport_state |= CMD_T_ACTIVE;
spin_unlock_irq(&cmd->t_state_lock); spin_unlock_irq(&cmd->t_state_lock);
if (!target_handle_task_attr(cmd)) if (!target_handle_task_attr(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