[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