[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210125183201.599174722@linuxfoundation.org>
Date: Mon, 25 Jan 2021 19:38:55 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Hannes Reinecke <hare@...e.de>,
Martin Wilck <mwilck@...e.com>, Christoph Hellwig <hch@....de>,
Mike Snitzer <snitzer@...hat.com>
Subject: [PATCH 5.4 13/86] dm: avoid filesystem lookup in dm_get_dev_t()
From: Hannes Reinecke <hare@...e.de>
commit 809b1e4945774c9ec5619a8f4e2189b7b3833c0c upstream.
This reverts commit
644bda6f3460 ("dm table: fall back to getting device using name_to_dev_t()")
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.
Fixes: 644bda6f3460 ("dm table: fall back to getting device using name_to_dev_t()")
Cc: stable@...r.kernel.org
Signed-off-by: Hannes Reinecke <hare@...e.de>
Signed-off-by: Martin Wilck <mwilck@...e.com>
Reviewed-by: Christoph Hellwig <hch@....de>
Signed-off-by: Mike Snitzer <snitzer@...hat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/md/dm-table.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -428,14 +428,23 @@ int dm_get_device(struct dm_target *ti,
{
int r;
dev_t dev;
+ unsigned int major, minor;
+ char dummy;
struct dm_dev_internal *dd;
struct dm_table *t = ti->table;
BUG_ON(!t);
- dev = dm_get_dev_t(path);
- if (!dev)
- return -ENODEV;
+ if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) {
+ /* Extract the major/minor numbers */
+ dev = MKDEV(major, minor);
+ if (MAJOR(dev) != major || MINOR(dev) != minor)
+ return -EOVERFLOW;
+ } else {
+ dev = dm_get_dev_t(path);
+ if (!dev)
+ return -ENODEV;
+ }
dd = find_device(&t->devices, dev);
if (!dd) {
Powered by blists - more mailing lists