diff options
Diffstat (limited to 'init/do_mounts.c')
| -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 | ||
