diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2008-05-06 22:31:33 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-05-14 10:37:57 -0700 |
commit | 30f2f0eb4bd2c43d10a8b0d872c6e5ad8f31c9a0 (patch) | |
tree | deb8d2a749cd737d9abead1b4cc8321d00dbaee4 /init | |
parent | 9604006d283fb67dda5ee9e0e15b7cc6c62e1557 (diff) |
block: do_mounts - accept root=<non-existant partition>
Some devices, like md, may create partitions only at first access,
so allow root= to be set to a valid non-existant partition of an
existing disk. This applies only to non-initramfs root mounting.
This fixes a regression from 2.6.24 which did allow this to happen and
broke some users machines :(
Acked-by: Neil Brown <neilb@suse.de>
Tested-by: Joao Luis Meloni Assirati <assirati@nonada.if.usp.br>
Cc: stable <stable@kernel.org>
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'init')
-rw-r--r-- | init/do_mounts.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c index 3885e70e775..660c1e50c91 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -76,6 +76,7 @@ dev_t name_to_dev_t(char *name) char s[32]; char *p; dev_t res = 0; + int part; if (strncmp(name, "/dev/", 5) != 0) { unsigned maj, min; @@ -106,7 +107,31 @@ dev_t name_to_dev_t(char *name) for (p = s; *p; p++) if (*p == '/') *p = '!'; - res = blk_lookup_devt(s); + res = blk_lookup_devt(s, 0); + if (res) + goto done; + + /* + * try non-existant, but valid partition, which may only exist + * after revalidating the disk, like partitioned md devices + */ + while (p > s && isdigit(p[-1])) + p--; + if (p == s || !*p || *p == '0') + goto fail; + + /* try disk name without <part number> */ + part = simple_strtoul(p, NULL, 10); + *p = '\0'; + res = blk_lookup_devt(s, part); + if (res) + goto done; + + /* try disk name without p<part number> */ + if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') + goto fail; + p[-1] = '\0'; + res = blk_lookup_devt(s, part); if (res) goto done; |