scsi: target: iscsi: Handle abort for WRITE_PENDING cmds
authorDmitry Bogdanov <d.bogdanov@yadro.com>
Sun, 19 Mar 2023 01:56:20 +0000 (20:56 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 24 Mar 2023 21:32:23 +0000 (17:32 -0400)
Sometimes an initiator does not send data for a WRITE command and tries to
abort it. The abort hangs waiting for frontend driver completion. iSCSI
driver waits for data and that timeout eventually initiates connection
reinstatment. The connection closing releases the commands in the
connection, but those aborted commands still did not handle the abort and
did not decrease a command ref counter. Because of that the connection
reinstatement hangs indefinitely and prevents re-login for that initiator.

Add handling in TCM of the abort for the WRITE_PENDING commands at
connection closing moment to make it possible to release them.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
[mnc: Rebase and expand comment]
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20230319015620.96006-10-michael.christie@oracle.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/target/iscsi/iscsi_target.c

index 07e196b44b91dae44571b717ae3771682dd1e0fb..834cce50f9b00ae5588abaf1c2c657203176ee39 100644 (file)
@@ -26,6 +26,7 @@
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
 
+#include <target/target_core_backend.h>
 #include <target/iscsi/iscsi_target_core.h>
 #include "iscsi_target_parameters.h"
 #include "iscsi_target_seq_pdu_list.h"
@@ -4236,6 +4237,16 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
                } else {
                        se_cmd->transport_state |= CMD_T_FABRIC_STOP;
                }
+
+               if (cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) {
+                       /*
+                        * We never submitted the cmd to LIO core, so we have
+                        * to tell LIO to perform the completion process.
+                        */
+                       spin_unlock_irq(&se_cmd->t_state_lock);
+                       target_complete_cmd(&cmd->se_cmd, SAM_STAT_TASK_ABORTED);
+                       continue;
+               }
                spin_unlock_irq(&se_cmd->t_state_lock);
        }
        spin_unlock_bh(&conn->cmd_lock);