aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Ehrenberg <dehrenberg@chromium.org>2015-02-10 18:20:51 -0500
committerMike Snitzer <snitzer@redhat.com>2015-04-15 12:10:19 -0400
commit644bda6f346038bce7ad3ed48f7044c10dde6d47 (patch)
tree7e3503be0a3160851dce4fab298508313ece95b9
parent283e7ad0241155710f99a9f39d13313a53336926 (diff)
dm table: fall back to getting device using name_to_dev_t()
If a device is used as the root filesystem, it can't be built off of devices which are within the root filesystem (just like command line arguments to root=). For this reason, Linux has a pseudo-filesystem for root= and MD initialization (based on the function name_to_dev_t) which handles different ways of specifying devices including PARTUUID and major:minor. Switch to using name_to_dev_t() in dm_get_device(). Rather than having DM assume that all things which are not major:minor are paths in an already-mounted filesystem, change dm_get_device() to first attempt to look up the device in the filesystem, and if not found it will fall back to using name_to_dev_t(). In terms of backwards compatibility, there are some cases where behavior will be different: - If you have a file in the current working directory named 1:2 and you initialze DM there, then it will try to use that file rather than the disk with that major:minor pair as a backing device. - Similarly for other bdev types which name_to_dev_t() knows how to interpret, the previous behavior was to repeatedly check for the existence of the file (e.g., while waiting for rootfs to come up) but the new behavior is to use the name_to_dev_t() interpretation. For example, if you have a file named /dev/ubiblock0_0 which is a symlink to /dev/sda3, but it is not yet present when DM starts to initialize, then the name_to_dev_t() interpretation will take precedence. These incompatibilities would only show up in really strange setups with bad practices so we shouldn't have to worry about them. Signed-off-by: Dan Ehrenberg <dehrenberg@chromium.org> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-table.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 8d025f33de92..e0f618b43c25 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -19,6 +19,7 @@
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/atomic.h> 20#include <linux/atomic.h>
21#include <linux/blk-mq.h> 21#include <linux/blk-mq.h>
22#include <linux/mount.h>
22 23
23#define DM_MSG_PREFIX "table" 24#define DM_MSG_PREFIX "table"
24 25
@@ -373,23 +374,18 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
373 int r; 374 int r;
374 dev_t uninitialized_var(dev); 375 dev_t uninitialized_var(dev);
375 struct dm_dev_internal *dd; 376 struct dm_dev_internal *dd;
376 unsigned int major, minor;
377 struct dm_table *t = ti->table; 377 struct dm_table *t = ti->table;
378 char dummy; 378 struct block_device *bdev;
379 379
380 BUG_ON(!t); 380 BUG_ON(!t);
381 381
382 if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) { 382 /* convert the path to a device */
383 /* Extract the major/minor numbers */ 383 bdev = lookup_bdev(path);
384 dev = MKDEV(major, minor); 384 if (IS_ERR(bdev)) {
385 if (MAJOR(dev) != major || MINOR(dev) != minor) 385 dev = name_to_dev_t(path);
386 return -EOVERFLOW; 386 if (!dev)
387 return -ENODEV;
387 } else { 388 } else {
388 /* convert the path to a device */
389 struct block_device *bdev = lookup_bdev(path);
390
391 if (IS_ERR(bdev))
392 return PTR_ERR(bdev);
393 dev = bdev->bd_dev; 389 dev = bdev->bd_dev;
394 bdput(bdev); 390 bdput(bdev);
395 } 391 }