diff options
-rw-r--r-- | init/do_mounts.c | 49 | ||||
-rw-r--r-- | net/ipv4/ipconfig.c | 10 |
2 files changed, 57 insertions, 2 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c index 9634ecf3743d..af9cda887a23 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -212,6 +212,7 @@ static int match_dev_by_label(struct device *dev, const void *data) * a colon. * 9) PARTLABEL=<name> with name being the GPT partition label. * MSDOS partitions do not support labels! + * 10) /dev/cifs represents Root_CIFS (0xfe) * * If name doesn't have fall into the categories above, we return (0,0). * block_class is used to check if something is a disk name. If the disk @@ -268,6 +269,9 @@ dev_t name_to_dev_t(const char *name) res = Root_NFS; if (strcmp(name, "nfs") == 0) goto done; + res = Root_CIFS; + if (strcmp(name, "cifs") == 0) + goto done; res = Root_RAM0; if (strcmp(name, "ram") == 0) goto done; @@ -501,6 +505,42 @@ static int __init mount_nfs_root(void) } #endif +#ifdef CONFIG_CIFS_ROOT + +extern int cifs_root_data(char **dev, char **opts); + +#define CIFSROOT_TIMEOUT_MIN 5 +#define CIFSROOT_TIMEOUT_MAX 30 +#define CIFSROOT_RETRY_MAX 5 + +static int __init mount_cifs_root(void) +{ + char *root_dev, *root_data; + unsigned int timeout; + int try, err; + + err = cifs_root_data(&root_dev, &root_data); + if (err != 0) + return 0; + + timeout = CIFSROOT_TIMEOUT_MIN; + for (try = 1; ; try++) { + err = do_mount_root(root_dev, "cifs", root_mountflags, + root_data); + if (err == 0) + return 1; + if (try > CIFSROOT_RETRY_MAX) + break; + + ssleep(timeout); + timeout <<= 1; + if (timeout > CIFSROOT_TIMEOUT_MAX) + timeout = CIFSROOT_TIMEOUT_MAX; + } + return 0; +} +#endif + #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) void __init change_floppy(char *fmt, ...) { @@ -542,6 +582,15 @@ void __init mount_root(void) ROOT_DEV = Root_FD0; } #endif +#ifdef CONFIG_CIFS_ROOT + if (ROOT_DEV == Root_CIFS) { + if (mount_cifs_root()) + return; + + printk(KERN_ERR "VFS: Unable to mount root fs via SMB, trying floppy.\n"); + ROOT_DEV = Root_FD0; + } +#endif #ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { /* rd_doload is 2 for a dual initrd/ramload setup */ diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 9bcca08efec9..32e20b758b68 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1483,10 +1483,10 @@ static int __init ip_auto_config(void) * missing values. */ if (ic_myaddr == NONE || -#ifdef CONFIG_ROOT_NFS +#if defined(CONFIG_ROOT_NFS) || defined(CONFIG_CIFS_ROOT) (root_server_addr == NONE && ic_servaddr == NONE && - ROOT_DEV == Root_NFS) || + (ROOT_DEV == Root_NFS || ROOT_DEV == Root_CIFS)) || #endif ic_first_dev->next) { #ifdef IPCONFIG_DYNAMIC @@ -1513,6 +1513,12 @@ static int __init ip_auto_config(void) goto try_try_again; } #endif +#ifdef CONFIG_CIFS_ROOT + if (ROOT_DEV == Root_CIFS) { + pr_err("IP-Config: Retrying forever (CIFS root)...\n"); + goto try_try_again; + } +#endif if (--retries) { pr_err("IP-Config: Reopening network devices...\n"); |