scsi: iscsi: Have abort handler get ref to conn
authorMike Christie <michael.christie@oracle.com>
Tue, 25 May 2021 18:18:04 +0000 (13:18 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 2 Jun 2021 05:28:21 +0000 (01:28 -0400)
If SCSI midlayer is aborting a task when we are tearing down the conn we
could free the conn while the abort thread is accessing the conn. This has
the abort handler get a ref to the conn so it won't be freed from under it.

Note: this is not needed for device/target reset because we are holding the
eh_mutex when accessing the conn.

Link: https://lore.kernel.org/r/20210525181821.7617-12-michael.christie@oracle.com
Reviewed-by: Lee Duncan <lduncan@suse.com>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/libiscsi.c

index ab39d7f65bbb09fd567675ecb2d6a0c3ce5b8492..6ca3d35a3d1113dc7fea9ebca6042f43c3eb458b 100644 (file)
@@ -2285,6 +2285,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
        }
 
        conn = session->leadconn;
+       iscsi_get_conn(conn->cls_conn);
        conn->eh_abort_cnt++;
        age = session->age;
 
@@ -2295,9 +2296,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
 
                spin_unlock(&session->back_lock);
-               spin_unlock_bh(&session->frwd_lock);
-               mutex_unlock(&session->eh_mutex);
-               return SUCCESS;
+               goto success;
        }
        ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
        __iscsi_get_task(task);
@@ -2364,6 +2363,7 @@ success_unlocked:
        ISCSI_DBG_EH(session, "abort success [sc %p itt 0x%x]\n",
                     sc, task->itt);
        iscsi_put_task(task);
+       iscsi_put_conn(conn->cls_conn);
        mutex_unlock(&session->eh_mutex);
        return SUCCESS;
 
@@ -2373,6 +2373,7 @@ failed_unlocked:
        ISCSI_DBG_EH(session, "abort failed [sc %p itt 0x%x]\n", sc,
                     task ? task->itt : 0);
        iscsi_put_task(task);
+       iscsi_put_conn(conn->cls_conn);
        mutex_unlock(&session->eh_mutex);
        return FAILED;
 }