Patch "scsi: storvsc: Fix handling of srb_status and capacity change events" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    scsi: storvsc: Fix handling of srb_status and capacity change events

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     scsi-storvsc-fix-handling-of-srb_status-and-capacity.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 7da41f2dd3fe0029c0a6411c8fe63390be4b92f3
Author: Michael Kelley <mikelley@xxxxxxxxxxxxx>
Date:   Wed Nov 9 10:48:42 2022 -0800

    scsi: storvsc: Fix handling of srb_status and capacity change events
    
    [ Upstream commit b8a5376c321b4669f7ffabc708fd30c3970f3084 ]
    
    Current handling of the srb_status is incorrect. Commit 52e1b3b3daa9
    ("scsi: storvsc: Correctly handle multiple flags in srb_status")
    is based on srb_status being a set of flags, when in fact only the
    2 high order bits are flags and the remaining 6 bits are an integer
    status. Because the integer values of interest mostly look like flags,
    the code actually works when treated that way.
    
    But in the interest of correctness going forward, fix this by treating
    the low 6 bits of srb_status as an integer status code. Add handling
    for SRB_STATUS_INVALID_REQUEST, which was the original intent of commit
    52e1b3b3daa9. Furthermore, treat the ERROR, ABORTED, and INVALID_REQUEST
    srb status codes as essentially equivalent for the cases we care about.
    There's no harm in doing so, and it isn't always clear which status code
    current or older versions of Hyper-V report for particular conditions.
    
    Treating the srb status codes as equivalent has the additional benefit
    of ensuring that capacity change events result in an immediate rescan
    so that the new size is known to Linux. Existing code checks SCSI
    sense data for capacity change events when the srb status is ABORTED.
    But capacity change events are also being observed when Hyper-V reports
    the srb status as ERROR. Without the immediate rescan, the new size
    isn't known until something else causes a rescan (such as running
    fdisk to expand a partition), and in the meantime, tools such as "lsblk"
    continue to report the old size.
    
    Fixes: 52e1b3b3daa9 ("scsi: storvsc: Correctly handle multiple flags in srb_status")
    Reported-by: Juan Tian <juantian@xxxxxxxxxxxxx>
    Signed-off-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/1668019722-1983-1-git-send-email-mikelley@xxxxxxxxxxxxx
    Signed-off-by: Wei Liu <wei.liu@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 3d03e1ca5820..6110dfd903f7 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -344,16 +344,21 @@ enum storvsc_request_type {
 };
 
 /*
- * SRB status codes and masks; a subset of the codes used here.
+ * SRB status codes and masks. In the 8-bit field, the two high order bits
+ * are flags, while the remaining 6 bits are an integer status code.  The
+ * definitions here include only the subset of the integer status codes that
+ * are tested for in this driver.
  */
-
 #define SRB_STATUS_AUTOSENSE_VALID	0x80
 #define SRB_STATUS_QUEUE_FROZEN		0x40
-#define SRB_STATUS_INVALID_LUN	0x20
-#define SRB_STATUS_SUCCESS	0x01
-#define SRB_STATUS_ABORTED	0x02
-#define SRB_STATUS_ERROR	0x04
-#define SRB_STATUS_DATA_OVERRUN	0x12
+
+/* SRB status integer codes */
+#define SRB_STATUS_SUCCESS		0x01
+#define SRB_STATUS_ABORTED		0x02
+#define SRB_STATUS_ERROR		0x04
+#define SRB_STATUS_INVALID_REQUEST	0x06
+#define SRB_STATUS_DATA_OVERRUN		0x12
+#define SRB_STATUS_INVALID_LUN		0x20
 
 #define SRB_STATUS(status) \
 	(status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
@@ -1032,38 +1037,25 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
 	void (*process_err_fn)(struct work_struct *work);
 	struct hv_host_device *host_dev = shost_priv(host);
 
-	/*
-	 * In some situations, Hyper-V sets multiple bits in the
-	 * srb_status, such as ABORTED and ERROR. So process them
-	 * individually, with the most specific bits first.
-	 */
-
-	if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) {
-		set_host_byte(scmnd, DID_NO_CONNECT);
-		process_err_fn = storvsc_remove_lun;
-		goto do_work;
-	}
+	switch (SRB_STATUS(vm_srb->srb_status)) {
+	case SRB_STATUS_ERROR:
+	case SRB_STATUS_ABORTED:
+	case SRB_STATUS_INVALID_REQUEST:
+		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) {
+			/* Check for capacity change */
+			if ((asc == 0x2a) && (ascq == 0x9)) {
+				process_err_fn = storvsc_device_scan;
+				/* Retry the I/O that triggered this. */
+				set_host_byte(scmnd, DID_REQUEUE);
+				goto do_work;
+			}
 
-	if (vm_srb->srb_status & SRB_STATUS_ABORTED) {
-		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
-		    /* Capacity data has changed */
-		    (asc == 0x2a) && (ascq == 0x9)) {
-			process_err_fn = storvsc_device_scan;
 			/*
-			 * Retry the I/O that triggered this.
+			 * Otherwise, let upper layer deal with the
+			 * error when sense message is present
 			 */
-			set_host_byte(scmnd, DID_REQUEUE);
-			goto do_work;
-		}
-	}
-
-	if (vm_srb->srb_status & SRB_STATUS_ERROR) {
-		/*
-		 * Let upper layer deal with error when
-		 * sense message is present.
-		 */
-		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
 			return;
+		}
 
 		/*
 		 * If there is an error; offline the device since all
@@ -1086,6 +1078,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
 		default:
 			set_host_byte(scmnd, DID_ERROR);
 		}
+		return;
+
+	case SRB_STATUS_INVALID_LUN:
+		set_host_byte(scmnd, DID_NO_CONNECT);
+		process_err_fn = storvsc_remove_lun;
+		goto do_work;
+
 	}
 	return;
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux