diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/do_mounts.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c index 0f6e1d985a3b..db6e5ee0e1db 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -398,15 +398,42 @@ out: | |||
398 | } | 398 | } |
399 | 399 | ||
400 | #ifdef CONFIG_ROOT_NFS | 400 | #ifdef CONFIG_ROOT_NFS |
401 | |||
402 | #define NFSROOT_TIMEOUT_MIN 5 | ||
403 | #define NFSROOT_TIMEOUT_MAX 30 | ||
404 | #define NFSROOT_RETRY_MAX 5 | ||
405 | |||
401 | static int __init mount_nfs_root(void) | 406 | static int __init mount_nfs_root(void) |
402 | { | 407 | { |
403 | char *root_dev, *root_data; | 408 | char *root_dev, *root_data; |
409 | unsigned int timeout; | ||
410 | int try, err; | ||
404 | 411 | ||
405 | if (nfs_root_data(&root_dev, &root_data) != 0) | 412 | err = nfs_root_data(&root_dev, &root_data); |
406 | return 0; | 413 | if (err != 0) |
407 | if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0) | ||
408 | return 0; | 414 | return 0; |
409 | return 1; | 415 | |
416 | /* | ||
417 | * The server or network may not be ready, so try several | ||
418 | * times. Stop after a few tries in case the client wants | ||
419 | * to fall back to other boot methods. | ||
420 | */ | ||
421 | timeout = NFSROOT_TIMEOUT_MIN; | ||
422 | for (try = 1; ; try++) { | ||
423 | err = do_mount_root(root_dev, "nfs", | ||
424 | root_mountflags, root_data); | ||
425 | if (err == 0) | ||
426 | return 1; | ||
427 | if (try > NFSROOT_RETRY_MAX) | ||
428 | break; | ||
429 | |||
430 | /* Wait, in case the server refused us immediately */ | ||
431 | ssleep(timeout); | ||
432 | timeout <<= 1; | ||
433 | if (timeout > NFSROOT_TIMEOUT_MAX) | ||
434 | timeout = NFSROOT_TIMEOUT_MAX; | ||
435 | } | ||
436 | return 0; | ||
410 | } | 437 | } |
411 | #endif | 438 | #endif |
412 | 439 | ||