scsi: qedi: Fix cleanup session block/unblock use
authorMike Christie <michael.christie@oracle.com>
Tue, 25 May 2021 18:18:18 +0000 (13:18 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Jul 2021 14:05:41 +0000 (16:05 +0200)
[ Upstream commit 0c72191da68638a479602dd515b587ada913184a ]

Drivers shouldn't be calling block/unblock session for cmd cleanup because
the functions can change the session state from under libiscsi.  This adds
a new a driver level bit so it can block all I/O the host while it drains
the card.

Link: https://lore.kernel.org/r/20210525181821.7617-26-michael.christie@oracle.com
Reviewed-by: Manish Rangankar <mrangankar@marvell.com>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/qedi/qedi.h
drivers/scsi/qedi/qedi_iscsi.c

index c342def..ce199a7 100644 (file)
@@ -284,6 +284,7 @@ struct qedi_ctx {
 #define QEDI_IN_RECOVERY       5
 #define QEDI_IN_OFFLINE                6
 #define QEDI_IN_SHUTDOWN       7
+#define QEDI_BLOCK_IO          8
 
        u8 mac[ETH_ALEN];
        u32 src_ip[4];
index 604c4f4..f51723e 100644 (file)
@@ -330,12 +330,22 @@ free_conn:
 
 void qedi_mark_device_missing(struct iscsi_cls_session *cls_session)
 {
-       iscsi_block_session(cls_session);
+       struct iscsi_session *session = cls_session->dd_data;
+       struct qedi_conn *qedi_conn = session->leadconn->dd_data;
+
+       spin_lock_bh(&session->frwd_lock);
+       set_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags);
+       spin_unlock_bh(&session->frwd_lock);
 }
 
 void qedi_mark_device_available(struct iscsi_cls_session *cls_session)
 {
-       iscsi_unblock_session(cls_session);
+       struct iscsi_session *session = cls_session->dd_data;
+       struct qedi_conn *qedi_conn = session->leadconn->dd_data;
+
+       spin_lock_bh(&session->frwd_lock);
+       clear_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags);
+       spin_unlock_bh(&session->frwd_lock);
 }
 
 static int qedi_bind_conn_to_iscsi_cid(struct qedi_ctx *qedi,
@@ -789,6 +799,9 @@ static int qedi_task_xmit(struct iscsi_task *task)
        if (test_bit(QEDI_IN_SHUTDOWN, &qedi_conn->qedi->flags))
                return -ENODEV;
 
+       if (test_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags))
+               return -EACCES;
+
        cmd->state = 0;
        cmd->task = NULL;
        cmd->use_slowpath = false;