scsi: target: core: UA on all LUNs after reset
authorDmitry Bogdanov <d.bogdanov@yadro.com>
Tue, 13 Sep 2022 16:36:02 +0000 (19:36 +0300)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 1 Oct 2022 09:06:53 +0000 (05:06 -0400)
Allocate UNIT ATTENTION "BUS DEVICE RESET OCCURRED" on all LUNs on all
target ports of the device upon reception of TMF LUN RESET.

This change passes libiscsi test SCSI.MultipathIO.Reset.

Link: https://lore.kernel.org/r/20220913163602.20597-1-d.bogdanov@yadro.com
Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/target/target_core_device.c
drivers/target/target_core_internal.h
drivers/target/target_core_transport.c

index b7f16ee8aa0e50bb00cc1cbdb51831acf64e3d17..cb4f7cc02f8fa131414f3000ea523950f59eea50 100644 (file)
@@ -284,6 +284,25 @@ void target_pr_kref_release(struct kref *kref)
        complete(&deve->pr_comp);
 }
 
+/*
+ * Establish UA condition on SCSI device - all LUNs
+ */
+void target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq)
+{
+       struct se_dev_entry *se_deve;
+       struct se_lun *lun;
+
+       spin_lock(&dev->se_port_lock);
+       list_for_each_entry(lun, &dev->dev_sep_list, lun_dev_link) {
+
+               spin_lock(&lun->lun_deve_lock);
+               list_for_each_entry(se_deve, &lun->lun_deve_list, lun_link)
+                       core_scsi3_ua_allocate(se_deve, asc, ascq);
+               spin_unlock(&lun->lun_deve_lock);
+       }
+       spin_unlock(&dev->se_port_lock);
+}
+
 static void
 target_luns_data_has_changed(struct se_node_acl *nacl, struct se_dev_entry *new,
                             bool skip_new)
index 30fcf69e1a1d59e7436776496cdc63ab6dc7e1ca..38a6d08f75b3427e9a738020291ac8de10705655 100644 (file)
@@ -89,6 +89,7 @@ int   target_configure_device(struct se_device *dev);
 void   target_free_device(struct se_device *);
 int    target_for_each_device(int (*fn)(struct se_device *dev, void *data),
                               void *data);
+void   target_dev_ua_allocate(struct se_device *dev, u8 asc, u8 ascq);
 
 /* target_core_configfs.c */
 extern struct configfs_item_operations target_core_dev_item_ops;
index 7838dc20f7130cb6635f02a996770316a5520754..5926316252eb98725c8fd5c3acc7d7f2c42e0af3 100644 (file)
@@ -3531,8 +3531,7 @@ static void target_tmr_work(struct work_struct *work)
                tmr->response = (!ret) ? TMR_FUNCTION_COMPLETE :
                                         TMR_FUNCTION_REJECTED;
                if (tmr->response == TMR_FUNCTION_COMPLETE) {
-                       target_ua_allocate_lun(cmd->se_sess->se_node_acl,
-                                              cmd->orig_fe_lun, 0x29,
+                       target_dev_ua_allocate(dev, 0x29,
                                               ASCQ_29H_BUS_DEVICE_RESET_FUNCTION_OCCURRED);
                }
                break;