[PATCH] Wait and retry mounting root device

From: Daniel Drake
Date: Tue Jan 04 2005 - 06:57:58 EST


This is based a patch by William Park <opengeometry@xxxxxxxx> included in
2.6.10-mm1, in order to fix booting from usb-storage devices which no longer
make their partitions immediately available.

While William's patch fixed the situation where you boot from a "root=8:1"
parameter (to correspond to /dev/sda1), it does not allow you to use
"root=/dev/sda1" (which apparently worked in 2.6.9 and earlier), because
the name-->dev_t discovery is done before the "retry" loop starts, and is
not retried during the loop.

This patch, which replaces William's, solves the above problems.

Signed-off-by: Daniel Drake <dsd@xxxxxxxxxx>


--- linux-2.6.10/init/do_mounts.c.orig 2005-01-04 12:01:37.933995432 +0000
+++ linux-2.6.10/init/do_mounts.c 2005-01-04 12:01:03.511228488 +0000
@@ -6,6 +6,7 @@
#include <linux/suspend.h>
#include <linux/root_dev.h>
#include <linux/security.h>
+#include <linux/delay.h>

#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
@@ -136,10 +137,12 @@

dev_t __init name_to_dev_t(char *name)
{
- char s[32];
+ char fullname[32], devname[32], absname[32];
char *p;
dev_t res = 0;
- int part;
+ int part = 0;
+ int tryabs = 0;
+ int tryagain = 20;

#ifdef CONFIG_SYSFS
int mkdir_err = sys_mkdir("/sys", 0700);
@@ -171,28 +174,54 @@

if (strlen(name) > 31)
goto fail;
- strcpy(s, name);
- for (p = s; *p; p++)
+
+ strcpy(absname, name);
+ for (p = absname; *p; p++)
if (*p == '/')
*p = '!';
- res = try_name(s, 0);
+
+ strcpy(fullname, absname);
+
+ while (p > absname && isdigit(p[-1]))
+ p--;
+
+ if (p > absname && *p && *p != '0') {
+ part = simple_strtoul(p, NULL, 10);
+ *p = '\0';
+ }
+
+ strcpy(devname, absname);
+
+ if (p >= absname + 2 && isdigit(p[-2]) && p[-1] == 'p') {
+ p[-1] = '\0';
+ tryabs = 1;
+ }
+
+retry:
+ res = try_name(fullname, 0);
if (res)
goto done;

- while (p > s && isdigit(p[-1]))
- p--;
- if (p == s || !*p || *p == '0')
- goto fail;
- part = simple_strtoul(p, NULL, 10);
- *p = '\0';
- res = try_name(s, part);
+ if (!part)
+ goto next;
+
+ res = try_name(devname, part);
if (res)
goto done;

- if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
- goto fail;
- p[-1] = '\0';
- res = try_name(s, part);
+ if (!tryabs)
+ goto next;
+
+ res = try_name(absname, part);
+ if (res)
+ goto done;
+
+next:
+ if (--tryagain) {
+ printk(KERN_WARNING "VFS: Root device '%s' not available, waiting %dsec\n", name, tryagain);
+ ssleep(1);
+ goto retry;
+ }
done:
#ifdef CONFIG_SYSFS
sys_umount("/sys", 0);