]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: hpsa: do-not-complete-cmds-for-deleted-devices
authorDon Brace <don.brace@microsemi.com>
Tue, 7 May 2019 18:32:26 +0000 (13:32 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 18 Jun 2019 23:46:18 +0000 (19:46 -0400)
Close up a rare multipath issue.

Close up small hole where a command completes after a device has been
removed from SML and before the device is re-added.

 - Mark device as removed in slave_destroy

 - Do not complete commands for deleted devices

Reviewed-by: Justin Lindley <justin.lindley@microsemi.com>
Reviewed-by: David Carroll <david.carroll@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h

index df447f1d63119caea767253fe766f9d16d93eabe..42d51951b61a4d844096055c774391f654e80610 100644 (file)
@@ -2141,6 +2141,7 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
        sdev->no_uld_attach = !sd || !sd->expose_device;
 
        if (sd) {
+               sd->was_removed = 0;
                if (sd->external) {
                        queue_depth = EXTERNAL_QD;
                        sdev->eh_timeout = HPSA_EH_PTRAID_TIMEOUT;
@@ -2160,7 +2161,12 @@ static int hpsa_slave_configure(struct scsi_device *sdev)
 
 static void hpsa_slave_destroy(struct scsi_device *sdev)
 {
-       /* nothing to do. */
+       struct hpsa_scsi_dev_t *hdev = NULL;
+
+       hdev = sdev->hostdata;
+
+       if (hdev)
+               hdev->was_removed = 1;
 }
 
 static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h)
@@ -2588,6 +2594,12 @@ static void complete_scsi_command(struct CommandList *cp)
        cmd->result = (DID_OK << 16);           /* host byte */
        cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
 
+       /* SCSI command has already been cleaned up in SML */
+       if (dev->was_removed) {
+               hpsa_cmd_resolve_and_free(h, cp);
+               return;
+       }
+
        if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1) {
                if (dev->physical_device && dev->expose_device &&
                        dev->removed) {
index 75210de71917e858878889849831400f430e1047..a013c16af5f10b8a2fcaf76903ab8e28440f1957 100644 (file)
@@ -65,6 +65,7 @@ struct hpsa_scsi_dev_t {
        u8 physical_device : 1;
        u8 expose_device;
        u8 removed : 1;                 /* device is marked for death */
+       u8 was_removed : 1;             /* device actually removed */
 #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
        unsigned char device_id[16];    /* from inquiry pg. 0x83 */
        u64 sas_address;