dm_get_dev_t() is just used to convert an arbitrary 'path' string
into a dev_t. It doesn't presume that the device is present; that
check will be done later, as the only caller is dm_get_device(),
which does a dm_get_table_device() later on, which will properly
open the device.
So if the path string already _is_ in major:minor representation
we can convert it directly, avoiding a recursion into the filesystem
to lookup the block device.
This avoids a hang in multipath_message() when the filesystem is
inaccessible.

Signed-off-by: Hannes Reinecke <[email protected]>
---
 drivers/md/dm-table.c     |  6 ++++++
 drivers/scsi/scsi_error.c | 18 ++++++++----------
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 0142dc0e6798..d71808be006b 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -411,7 +411,13 @@ dev_t dm_get_dev_t(const char *path)
 {
        dev_t dev;
        struct block_device *bdev;
+       unsigned int maj, min;
 
+       if (sscanf(path, "%u:%u", &maj, &min) == 2) {
+               dev = MKDEV(maj, min);
+               if (maj == MAJOR(dev) && min == MINOR(dev))
+                       return dev;
+       }
        bdev = lookup_bdev(path);
        if (IS_ERR(bdev))
                dev = name_to_dev_t(path);
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 6e01e90d83af..deee3e99aed0 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -133,16 +133,6 @@ scmd_eh_abort_handler(struct work_struct *work)
        struct scsi_device *sdev = scmd->device;
        int rtn;
 
-#ifndef __GENKSYMS__
-       if (scmd->eh_eflags & SCSI_EH_INTERNAL_TIMEOUT) {
-               SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
-                       "internal timeout\n"));
-               set_host_byte(scmd, DID_TIME_OUT);
-               scmd->eh_eflags &= ~SCSI_EH_INTERNAL_TIMEOUT;
-               scsi_finish_command(scmd);
-               return;
-       }
-#endif
        if (scsi_host_eh_past_deadline(sdev->host)) {
                SCSI_LOG_ERROR_RECOVERY(3,
                        scmd_printk(KERN_INFO, scmd,
@@ -934,6 +924,14 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd 
*scmd)
 static int scsi_try_to_abort_cmd(struct scsi_host_template *hostt,
                                 struct scsi_cmnd *scmd)
 {
+#ifndef __GENKSYMS__
+       if (scmd->eh_eflags & SCSI_EH_INTERNAL_TIMEOUT) {
+               SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+                       "internal timeout\n"));
+               scmd->eh_eflags &= ~SCSI_EH_INTERNAL_TIMEOUT;
+               return SUCCESS;
+       }
+#endif
        if (!hostt->eh_abort_handler)
                return FAILED;
 
-- 
2.16.4

--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to