scsi: core: Treat device offline as a failure
authorJason Yan <yanaijie@huawei.com>
Tue, 30 Mar 2021 11:47:27 +0000 (19:47 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 10 May 2021 17:24:03 +0000 (13:24 -0400)
When a SCSI device is offline a MODE SENSE command will return a result
with only DID_NO_CONNECT set. In sd_read_write_protect_flag() only the
status byte of the result is checked. Despite a returned status of
DID_NO_CONNECT the command is considered successful and we read
sdkp->write_prot from a buffer containing garbage.

Modify scsi_status_is_good() to treat DID_NO_CONNECT as a failure case.

Link: https://lore.kernel.org/r/20210330114727.234467-1-yanaijie@huawei.com
Signed-off-by: Jason Yan <yanaijie@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
include/scsi/scsi.h

index 246ced4..7f39240 100644 (file)
@@ -30,32 +30,6 @@ enum scsi_timeouts {
  */
 #define SCAN_WILD_CARD ~0
 
-/** scsi_status_is_good - check the status return.
- *
- * @status: the status passed up from the driver (including host and
- *          driver components)
- *
- * This returns true for known good conditions that may be treated as
- * command completed normally
- */
-static inline int scsi_status_is_good(int status)
-{
-       /*
-        * FIXME: bit0 is listed as reserved in SCSI-2, but is
-        * significant in SCSI-3.  For now, we follow the SCSI-2
-        * behaviour and ignore reserved bits.
-        */
-       status &= 0xfe;
-       return ((status == SAM_STAT_GOOD) ||
-               (status == SAM_STAT_CONDITION_MET) ||
-               /* Next two "intermediate" statuses are obsolete in SAM-4 */
-               (status == SAM_STAT_INTERMEDIATE) ||
-               (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
-               /* FIXME: this is obsolete in SAM-3 */
-               (status == SAM_STAT_COMMAND_TERMINATED));
-}
-
-
 /*
  * standard mode-select header prepended to all mode-select commands
  */
@@ -277,4 +251,32 @@ enum scsi_disposition {
 /* Used to obtain the PCI location of a device */
 #define SCSI_IOCTL_GET_PCI             0x5387
 
+/** scsi_status_is_good - check the status return.
+ *
+ * @status: the status passed up from the driver (including host and
+ *          driver components)
+ *
+ * This returns true for known good conditions that may be treated as
+ * command completed normally
+ */
+static inline int scsi_status_is_good(int status)
+{
+       if (host_byte(status) == DID_NO_CONNECT)
+               return 0;
+
+       /*
+        * FIXME: bit0 is listed as reserved in SCSI-2, but is
+        * significant in SCSI-3.  For now, we follow the SCSI-2
+        * behaviour and ignore reserved bits.
+        */
+       status &= 0xfe;
+       return ((status == SAM_STAT_GOOD) ||
+               (status == SAM_STAT_CONDITION_MET) ||
+               /* Next two "intermediate" statuses are obsolete in SAM-4 */
+               (status == SAM_STAT_INTERMEDIATE) ||
+               (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) ||
+               /* FIXME: this is obsolete in SAM-3 */
+               (status == SAM_STAT_COMMAND_TERMINATED));
+}
+
 #endif /* _SCSI_SCSI_H */