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 c0851a8e030..ef6478fbb54 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -360,15 +360,42 @@ out: | |||
360 | } | 360 | } |
361 | 361 | ||
362 | #ifdef CONFIG_ROOT_NFS | 362 | #ifdef CONFIG_ROOT_NFS |
363 | |||
364 | #define NFSROOT_TIMEOUT_MIN 5 | ||
365 | #define NFSROOT_TIMEOUT_MAX 30 | ||
366 | #define NFSROOT_RETRY_MAX 5 | ||
367 | |||
363 | static int __init mount_nfs_root(void) | 368 | static int __init mount_nfs_root(void) |
364 | { | 369 | { |
365 | char *root_dev, *root_data; | 370 | char *root_dev, *root_data; |
371 | unsigned int timeout; | ||
372 | int try, err; | ||
366 | 373 | ||
367 | if (nfs_root_data(&root_dev, &root_data) != 0) | 374 | err = nfs_root_data(&root_dev, &root_data); |
368 | return 0; | 375 | if (err != 0) |
369 | if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0) | ||
370 | return 0; | 376 | return 0; |
371 | return 1; | 377 | |
378 | /* | ||
379 | * The server or network may not be ready, so try several | ||
380 | * times. Stop after a few tries in case the client wants | ||
381 | * to fall back to other boot methods. | ||
382 | */ | ||
383 | timeout = NFSROOT_TIMEOUT_MIN; | ||
384 | for (try = 1; ; try++) { | ||
385 | err = do_mount_root(root_dev, "nfs", | ||
386 | root_mountflags, root_data); | ||
387 | if (err == 0) | ||
388 | return 1; | ||
389 | if (try > NFSROOT_RETRY_MAX) | ||
390 | break; | ||
391 | |||
392 | /* Wait, in case the server refused us immediately */ | ||
393 | ssleep(timeout); | ||
394 | timeout <<= 1; | ||
395 | if (timeout > NFSROOT_TIMEOUT_MAX) | ||
396 | timeout = NFSROOT_TIMEOUT_MAX; | ||
397 | } | ||
398 | return 0; | ||
372 | } | 399 | } |
373 | #endif | 400 | #endif |
374 | 401 | ||