[dm-devel] [PATCH] dm: avoid filesystem lookup in dm_get_dev_t()

Hannes Reinecke hare at suse.de
Thu Dec 10 09:24:59 UTC 2020


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 <hare at suse.de>
---
 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




More information about the dm-devel mailing list