Blame view
init/do_mounts.c
15.6 KB
457c89965 treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 |
#include <linux/module.h> #include <linux/sched.h> #include <linux/ctype.h> #include <linux/fd.h> #include <linux/tty.h> #include <linux/suspend.h> #include <linux/root_dev.h> #include <linux/security.h> #include <linux/delay.h> |
dd2a345f8 Display all possi... |
11 |
#include <linux/genhd.h> |
d53d9f16e [PATCH] name_to_d... |
12 |
#include <linux/mount.h> |
d779249ed Driver Core: add ... |
13 |
#include <linux/device.h> |
46595390e init/do_mounts.c:... |
14 |
#include <linux/init.h> |
011e3fcd1 proper prototype ... |
15 |
#include <linux/fs.h> |
82c8253ac init/do_mounts.c ... |
16 |
#include <linux/initrd.h> |
22a9d6456 async: Asynchrono... |
17 |
#include <linux/async.h> |
5ad4e53bd Get rid of indire... |
18 |
#include <linux/fs_struct.h> |
5a0e3ad6a include cleanup: ... |
19 |
#include <linux/slab.h> |
57f150a58 initmpfs: move ro... |
20 |
#include <linux/ramfs.h> |
16203a7a9 initmpfs: make ro... |
21 |
#include <linux/shmem_fs.h> |
1da177e4c Linux-2.6.12-rc2 |
22 23 24 25 |
#include <linux/nfs_fs.h> #include <linux/nfs_fs_sb.h> #include <linux/nfs_mount.h> |
4f5b246b3 md: move the earl... |
26 |
#include <linux/raid/detect.h> |
e262e32d6 vfs: Suppress MS_... |
27 |
#include <uapi/linux/mount.h> |
1da177e4c Linux-2.6.12-rc2 |
28 29 |
#include "do_mounts.h" |
9b04c997b [PATCH] vfs: MS_V... |
30 |
int root_mountflags = MS_RDONLY | MS_SILENT; |
f56f6d30c make init/do_moun... |
31 |
static char * __initdata root_device_name; |
1da177e4c Linux-2.6.12-rc2 |
32 |
static char __initdata saved_root_name[64]; |
79975f132 init: add root=PA... |
33 |
static int root_wait; |
1da177e4c Linux-2.6.12-rc2 |
34 |
|
1da177e4c Linux-2.6.12-rc2 |
35 |
dev_t ROOT_DEV; |
1da177e4c Linux-2.6.12-rc2 |
36 37 |
static int __init load_ramdisk(char *str) { |
c8376994c initrd: remove su... |
38 39 |
pr_warn("ignoring the deprecated load_ramdisk= option "); |
1da177e4c Linux-2.6.12-rc2 |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
return 1; } __setup("load_ramdisk=", load_ramdisk); static int __init readonly(char *str) { if (*str) return 0; root_mountflags |= MS_RDONLY; return 1; } static int __init readwrite(char *str) { if (*str) return 0; root_mountflags &= ~MS_RDONLY; return 1; } __setup("ro", readonly); __setup("rw", readwrite); |
6d0aed7a3 do_mounts: only e... |
62 |
#ifdef CONFIG_BLOCK |
1ad7e8994 block: store part... |
63 64 65 66 |
struct uuidcmp { const char *uuid; int len; }; |
b5af921ec init: add support... |
67 68 69 |
/** * match_dev_by_uuid - callback for finding a partition using its uuid * @dev: device passed in by the caller |
1ad7e8994 block: store part... |
70 |
* @data: opaque pointer to the desired struct uuidcmp to match |
b5af921ec init: add support... |
71 72 73 |
* * Returns 1 if the device matches, and 0 otherwise. */ |
9f3b795a6 driver-core: cons... |
74 |
static int match_dev_by_uuid(struct device *dev, const void *data) |
b5af921ec init: add support... |
75 |
{ |
0d02129e7 block: merge stru... |
76 |
struct block_device *bdev = dev_to_bdev(dev); |
9f3b795a6 driver-core: cons... |
77 |
const struct uuidcmp *cmp = data; |
b5af921ec init: add support... |
78 |
|
0d02129e7 block: merge stru... |
79 80 |
if (!bdev->bd_meta_info || strncasecmp(cmp->uuid, bdev->bd_meta_info->uuid, cmp->len)) |
013b0e96a init: cleanup mat... |
81 |
return 0; |
b5af921ec init: add support... |
82 |
return 1; |
b5af921ec init: add support... |
83 |
} |
b5af921ec init: add support... |
84 85 |
/** * devt_from_partuuid - looks up the dev_t of a partition by its UUID |
a68b31080 init/do_mounts.c:... |
86 |
* @uuid_str: char array containing ascii UUID |
b5af921ec init: add support... |
87 88 89 90 91 |
* * The function will return the first partition which contains a matching * UUID value in its partition_meta_info struct. This does not search * by filesystem UUIDs. * |
a68b31080 init/do_mounts.c:... |
92 |
* If @uuid_str is followed by a "/PARTNROFF=%d", then the number will be |
79975f132 init: add root=PA... |
93 94 |
* extracted and used as an offset from the partition identified by the UUID. * |
b5af921ec init: add support... |
95 96 |
* Returns the matching dev_t on success or 0 on failure. */ |
1ad7e8994 block: store part... |
97 |
static dev_t devt_from_partuuid(const char *uuid_str) |
b5af921ec init: add support... |
98 |
{ |
1ad7e8994 block: store part... |
99 |
struct uuidcmp cmp; |
b5af921ec init: add support... |
100 |
struct device *dev = NULL; |
e036bb8e0 init: refactor de... |
101 |
dev_t devt = 0; |
79975f132 init: add root=PA... |
102 |
int offset = 0; |
283f8fc03 init: reduce PART... |
103 |
char *slash; |
79975f132 init: add root=PA... |
104 |
|
1ad7e8994 block: store part... |
105 |
cmp.uuid = uuid_str; |
1ad7e8994 block: store part... |
106 |
|
283f8fc03 init: reduce PART... |
107 |
slash = strchr(uuid_str, '/'); |
79975f132 init: add root=PA... |
108 |
/* Check for optional partition number offset attributes. */ |
283f8fc03 init: reduce PART... |
109 |
if (slash) { |
79975f132 init: add root=PA... |
110 |
char c = 0; |
e036bb8e0 init: refactor de... |
111 |
|
79975f132 init: add root=PA... |
112 |
/* Explicitly fail on poor PARTUUID syntax. */ |
e036bb8e0 init: refactor de... |
113 114 |
if (sscanf(slash + 1, "PARTNROFF=%d%c", &offset, &c) != 1) goto clear_root_wait; |
283f8fc03 init: reduce PART... |
115 116 117 118 |
cmp.len = slash - uuid_str; } else { cmp.len = strlen(uuid_str); } |
e036bb8e0 init: refactor de... |
119 120 |
if (!cmp.len) goto clear_root_wait; |
b5af921ec init: add support... |
121 |
|
e036bb8e0 init: refactor de... |
122 |
dev = class_find_device(&block_class, NULL, &cmp, &match_dev_by_uuid); |
b5af921ec init: add support... |
123 |
if (!dev) |
e036bb8e0 init: refactor de... |
124 |
return 0; |
79975f132 init: add root=PA... |
125 |
|
e036bb8e0 init: refactor de... |
126 127 128 129 130 |
if (offset) { /* * Attempt to find the requested partition by adding an offset * to the partition number found by UUID. */ |
c97d93c31 block: factor out... |
131 132 |
devt = part_devt(dev_to_disk(dev), dev_to_bdev(dev)->bd_partno + offset); |
e036bb8e0 init: refactor de... |
133 134 |
} else { devt = dev->devt; |
79975f132 init: add root=PA... |
135 |
} |
79975f132 init: add root=PA... |
136 |
put_device(dev); |
e036bb8e0 init: refactor de... |
137 138 139 140 141 142 143 144 145 146 147 148 |
return devt; clear_root_wait: pr_err("VFS: PARTUUID= is invalid. " "Expected PARTUUID=<valid-uuid-id>[/PARTNROFF=%%d] "); if (root_wait) pr_err("Disabling rootwait; root= is invalid. "); root_wait = 0; return 0; |
b5af921ec init: add support... |
149 |
} |
f027c34d8 init/do_mounts.c:... |
150 151 152 153 154 155 156 157 158 159 |
/** * match_dev_by_label - callback for finding a partition using its label * @dev: device passed in by the caller * @data: opaque pointer to the label to match * * Returns 1 if the device matches, and 0 otherwise. */ static int match_dev_by_label(struct device *dev, const void *data) { |
0d02129e7 block: merge stru... |
160 |
struct block_device *bdev = dev_to_bdev(dev); |
f027c34d8 init/do_mounts.c:... |
161 |
const char *label = data; |
f027c34d8 init/do_mounts.c:... |
162 |
|
0d02129e7 block: merge stru... |
163 |
if (!bdev->bd_meta_info || strcmp(label, bdev->bd_meta_info->volname)) |
013b0e96a init: cleanup mat... |
164 165 |
return 0; return 1; |
f027c34d8 init/do_mounts.c:... |
166 |
} |
c2637e80a init: refactor na... |
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
static dev_t devt_from_partlabel(const char *label) { struct device *dev; dev_t devt = 0; dev = class_find_device(&block_class, NULL, label, &match_dev_by_label); if (dev) { devt = dev->devt; put_device(dev); } return devt; } static dev_t devt_from_devname(const char *name) { dev_t devt = 0; int part; char s[32]; char *p; if (strlen(name) > 31) return 0; strcpy(s, name); for (p = s; *p; p++) { if (*p == '/') *p = '!'; } devt = blk_lookup_devt(s, 0); if (devt) return devt; /* * Try non-existent, but valid partition, which may only exist after * opening the device, like partitioned md devices. */ while (p > s && isdigit(p[-1])) p--; if (p == s || !*p || *p == '0') return 0; /* try disk name without <part number> */ part = simple_strtoul(p, NULL, 10); *p = '\0'; devt = blk_lookup_devt(s, part); if (devt) return devt; /* try disk name without p<part number> */ if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') return 0; p[-1] = '\0'; return blk_lookup_devt(s, part); } #endif /* CONFIG_BLOCK */ static dev_t devt_from_devnum(const char *name) { unsigned maj, min, offset; dev_t devt = 0; char *p, dummy; if (sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2 || sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3) { devt = MKDEV(maj, min); if (maj != MAJOR(devt) || min != MINOR(devt)) return 0; } else { devt = new_decode_dev(simple_strtoul(name, &p, 16)); if (*p) return 0; } return devt; } |
b5af921ec init: add support... |
244 |
|
1da177e4c Linux-2.6.12-rc2 |
245 246 247 |
/* * Convert a name into device number. We accept the following variants: * |
0bf37ae4c init/do_mounts: b... |
248 249 |
* 1) <hex_major><hex_minor> device number in hexadecimal represents itself * no leading 0x, for example b302. |
1da177e4c Linux-2.6.12-rc2 |
250 251 252 253 254 255 |
* 2) /dev/nfs represents Root_NFS (0xff) * 3) /dev/<disk_name> represents the device number of disk * 4) /dev/<disk_name><decimal> represents the device number * of partition - device number of disk plus the partition number * 5) /dev/<disk_name>p<decimal> - same as the above, that form is * used when disk name of partitioned disk ends on a digit. |
b5af921ec init: add support... |
256 257 |
* 6) PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF representing the * unique id of a partition if the partition table provides it. |
d33b98fc8 block: partition:... |
258 259 260 261 |
* The UUID may be either an EFI/GPT UUID, or refer to an MSDOS * partition using the format SSSSSSSS-PP, where SSSSSSSS is a zero- * filled hex representation of the 32-bit "NT disk signature", and PP * is a zero-filled hex representation of the 1-based partition number. |
79975f132 init: add root=PA... |
262 263 |
* 7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to * a partition with a known unique id. |
6c251611c init/do_mounts.c:... |
264 265 |
* 8) <major>:<minor> major and minor number of the device separated by * a colon. |
f027c34d8 init/do_mounts.c:... |
266 267 |
* 9) PARTLABEL=<name> with name being the GPT partition label. * MSDOS partitions do not support labels! |
8902dd526 init: Support mou... |
268 |
* 10) /dev/cifs represents Root_CIFS (0xfe) |
1da177e4c Linux-2.6.12-rc2 |
269 |
* |
edfaa7c36 Driver core: conv... |
270 271 272 273 |
* 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 * name contains slashes, the device name has them replaced with * bangs. |
1da177e4c Linux-2.6.12-rc2 |
274 |
*/ |
e6e20a7a5 init: export name... |
275 |
dev_t name_to_dev_t(const char *name) |
1da177e4c Linux-2.6.12-rc2 |
276 |
{ |
c2637e80a init: refactor na... |
277 278 279 280 281 282 |
if (strcmp(name, "/dev/nfs") == 0) return Root_NFS; if (strcmp(name, "/dev/cifs") == 0) return Root_CIFS; if (strcmp(name, "/dev/ram") == 0) return Root_RAM0; |
6d0aed7a3 do_mounts: only e... |
283 |
#ifdef CONFIG_BLOCK |
c2637e80a init: refactor na... |
284 285 286 287 288 289 |
if (strncmp(name, "PARTUUID=", 9) == 0) return devt_from_partuuid(name + 9); if (strncmp(name, "PARTLABEL=", 10) == 0) return devt_from_partlabel(name + 10); if (strncmp(name, "/dev/", 5) == 0) return devt_from_devname(name + 5); |
6d0aed7a3 do_mounts: only e... |
290 |
#endif |
c2637e80a init: refactor na... |
291 |
return devt_from_devnum(name); |
1da177e4c Linux-2.6.12-rc2 |
292 |
} |
e6e20a7a5 init: export name... |
293 |
EXPORT_SYMBOL_GPL(name_to_dev_t); |
1da177e4c Linux-2.6.12-rc2 |
294 295 296 297 298 299 300 301 |
static int __init root_dev_setup(char *line) { strlcpy(saved_root_name, line, sizeof(saved_root_name)); return 1; } __setup("root=", root_dev_setup); |
cc1ed7542 init: wait for as... |
302 303 304 305 306 307 308 309 310 |
static int __init rootwait_setup(char *str) { if (*str) return 0; root_wait = 1; return 1; } __setup("rootwait", rootwait_setup); |
1da177e4c Linux-2.6.12-rc2 |
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
static char * __initdata root_mount_data; static int __init root_data_setup(char *str) { root_mount_data = str; return 1; } static char * __initdata root_fs_names; static int __init fs_names_setup(char *str) { root_fs_names = str; return 1; } static unsigned int __initdata root_delay; static int __init root_delay_setup(char *str) { root_delay = simple_strtoul(str, NULL, 0); return 1; } __setup("rootflags=", root_data_setup); __setup("rootfstype=", fs_names_setup); __setup("rootdelay=", root_delay_setup); |
b51593c4c init/do_mounts.c:... |
335 336 |
/* This can return zero length strings. Caller should check */ static int __init split_fs_names(char *page, size_t size, char *names) |
1da177e4c Linux-2.6.12-rc2 |
337 |
{ |
b51593c4c init/do_mounts.c:... |
338 |
int count = 1; |
6e7c1770a fs: simplify get_... |
339 |
char *p = page; |
1da177e4c Linux-2.6.12-rc2 |
340 |
|
b51593c4c init/do_mounts.c:... |
341 |
strlcpy(p, root_fs_names, size); |
6e7c1770a fs: simplify get_... |
342 |
while (*p++) { |
b51593c4c init/do_mounts.c:... |
343 |
if (p[-1] == ',') { |
6e7c1770a fs: simplify get_... |
344 |
p[-1] = '\0'; |
b51593c4c init/do_mounts.c:... |
345 346 |
count++; } |
1da177e4c Linux-2.6.12-rc2 |
347 |
} |
e24d12b74 init: split get_f... |
348 |
|
6e7c1770a fs: simplify get_... |
349 |
return count; |
1da177e4c Linux-2.6.12-rc2 |
350 |
} |
cccaa5e33 init: use do_moun... |
351 352 |
static int __init do_mount_root(const char *name, const char *fs, const int flags, const void *data) |
1da177e4c Linux-2.6.12-rc2 |
353 |
{ |
d8c9584ea vfs: prefer ->den... |
354 |
struct super_block *s; |
7de7de7ca Fix root mounting... |
355 356 |
struct page *p = NULL; char *data_page = NULL; |
cccaa5e33 init: use do_moun... |
357 |
int ret; |
7de7de7ca Fix root mounting... |
358 |
if (data) { |
c60166f04 init: add an init... |
359 |
/* init_mount() requires a full page as fifth argument */ |
7de7de7ca Fix root mounting... |
360 361 362 363 |
p = alloc_page(GFP_KERNEL); if (!p) return -ENOMEM; data_page = page_address(p); |
c60166f04 init: add an init... |
364 |
/* zero-pad. init_mount() will make sure it's terminated */ |
7de7de7ca Fix root mounting... |
365 366 |
strncpy(data_page, data, PAGE_SIZE); } |
cccaa5e33 init: use do_moun... |
367 |
|
c60166f04 init: add an init... |
368 |
ret = init_mount(name, "/root", fs, flags, data_page); |
cccaa5e33 init: use do_moun... |
369 370 |
if (ret) goto out; |
1da177e4c Linux-2.6.12-rc2 |
371 |
|
db63f1e31 init: add an init... |
372 |
init_chdir("/root"); |
d8c9584ea vfs: prefer ->den... |
373 374 |
s = current->fs->pwd.dentry->d_sb; ROOT_DEV = s->s_dev; |
80cdc6dae fs: use appropria... |
375 376 377 |
printk(KERN_INFO "VFS: Mounted root (%s filesystem)%s on device %u:%u. ", |
d8c9584ea vfs: prefer ->den... |
378 |
s->s_type->name, |
bc98a42c1 VFS: Convert sb->... |
379 |
sb_rdonly(s) ? " readonly" : "", |
d8c9584ea vfs: prefer ->den... |
380 |
MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); |
cccaa5e33 init: use do_moun... |
381 382 |
out: |
7de7de7ca Fix root mounting... |
383 384 |
if (p) put_page(p); |
cccaa5e33 init: use do_moun... |
385 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
386 387 388 389 |
} void __init mount_block_root(char *name, int flags) { |
75f296d93 kmemcheck: stop u... |
390 |
struct page *page = alloc_page(GFP_KERNEL); |
a608ca21f vfs: allocate pag... |
391 |
char *fs_names = page_address(page); |
1da177e4c Linux-2.6.12-rc2 |
392 393 |
char *p; char b[BDEVNAME_SIZE]; |
6e7c1770a fs: simplify get_... |
394 |
int num_fs, i; |
1da177e4c Linux-2.6.12-rc2 |
395 |
|
ea3edd4dc block: remove __b... |
396 397 |
scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)", MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); |
e24d12b74 init: split get_f... |
398 |
if (root_fs_names) |
b51593c4c init/do_mounts.c:... |
399 |
num_fs = split_fs_names(fs_names, PAGE_SIZE, root_fs_names); |
e24d12b74 init: split get_f... |
400 |
else |
6e7c1770a fs: simplify get_... |
401 |
num_fs = list_bdev_fs_names(fs_names, PAGE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
402 |
retry: |
6e7c1770a fs: simplify get_... |
403 |
for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) { |
b51593c4c init/do_mounts.c:... |
404 405 406 407 408 |
int err; if (!*p) continue; err = do_mount_root(name, p, flags, root_mount_data); |
1da177e4c Linux-2.6.12-rc2 |
409 410 411 412 |
switch (err) { case 0: goto out; case -EACCES: |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 416 417 418 |
case -EINVAL: continue; } /* * Allow the user to distinguish between failed sys_open * and bad superblock on root device. |
dd2a345f8 Display all possi... |
419 |
* and give them a list of the available devices |
1da177e4c Linux-2.6.12-rc2 |
420 |
*/ |
0e0cb892a init/do_mounts.c:... |
421 422 423 |
printk("VFS: Cannot open root device \"%s\" or %s: error %d ", root_device_name, b, err); |
dd2a345f8 Display all possi... |
424 425 |
printk("Please append a correct \"root=\" boot option; here are the available partitions: "); |
1da177e4c Linux-2.6.12-rc2 |
426 |
|
dd2a345f8 Display all possi... |
427 |
printk_all_partitions(); |
1da177e4c Linux-2.6.12-rc2 |
428 429 |
panic("VFS: Unable to mount root fs on %s", b); } |
e462ec50c VFS: Differentiat... |
430 431 |
if (!(flags & SB_RDONLY)) { flags |= SB_RDONLY; |
10975933d init: fix read-wr... |
432 433 |
goto retry; } |
be6e028b6 [PATCH] root moun... |
434 |
|
dd2a345f8 Display all possi... |
435 436 437 |
printk("List of all partitions: "); printk_all_partitions(); |
be6e028b6 [PATCH] root moun... |
438 |
printk("No filesystem could mount root, tried: "); |
6e7c1770a fs: simplify get_... |
439 |
for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) |
be6e028b6 [PATCH] root moun... |
440 441 442 |
printk(" %s", p); printk(" "); |
9361401eb [PATCH] BLOCK: Ma... |
443 |
panic("VFS: Unable to mount root fs on %s", b); |
1da177e4c Linux-2.6.12-rc2 |
444 |
out: |
a608ca21f vfs: allocate pag... |
445 |
put_page(page); |
1da177e4c Linux-2.6.12-rc2 |
446 447 448 |
} #ifdef CONFIG_ROOT_NFS |
43717c7da NFS: Retry mounti... |
449 450 451 452 |
#define NFSROOT_TIMEOUT_MIN 5 #define NFSROOT_TIMEOUT_MAX 30 #define NFSROOT_RETRY_MAX 5 |
1da177e4c Linux-2.6.12-rc2 |
453 454 |
static int __init mount_nfs_root(void) { |
56463e50d NFS: Use super.c ... |
455 |
char *root_dev, *root_data; |
43717c7da NFS: Retry mounti... |
456 457 |
unsigned int timeout; int try, err; |
1da177e4c Linux-2.6.12-rc2 |
458 |
|
43717c7da NFS: Retry mounti... |
459 460 |
err = nfs_root_data(&root_dev, &root_data); if (err != 0) |
56463e50d NFS: Use super.c ... |
461 |
return 0; |
43717c7da NFS: Retry mounti... |
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
/* * The server or network may not be ready, so try several * times. Stop after a few tries in case the client wants * to fall back to other boot methods. */ timeout = NFSROOT_TIMEOUT_MIN; for (try = 1; ; try++) { err = do_mount_root(root_dev, "nfs", root_mountflags, root_data); if (err == 0) return 1; if (try > NFSROOT_RETRY_MAX) break; /* Wait, in case the server refused us immediately */ ssleep(timeout); timeout <<= 1; if (timeout > NFSROOT_TIMEOUT_MAX) timeout = NFSROOT_TIMEOUT_MAX; } return 0; |
1da177e4c Linux-2.6.12-rc2 |
484 485 |
} #endif |
8902dd526 init: Support mou... |
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
#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 |
f9259be6a init: allow mount... |
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 |
static bool __init fs_is_nodev(char *fstype) { struct file_system_type *fs = get_fs_type(fstype); bool ret = false; if (fs) { ret = !(fs->fs_flags & FS_REQUIRES_DEV); put_filesystem(fs); } return ret; } static int __init mount_nodev_root(void) { char *fs_names, *fstype; int err = -EINVAL; |
6e7c1770a fs: simplify get_... |
538 |
int num_fs, i; |
f9259be6a init: allow mount... |
539 540 541 542 |
fs_names = (void *)__get_free_page(GFP_KERNEL); if (!fs_names) return -EINVAL; |
b51593c4c init/do_mounts.c:... |
543 |
num_fs = split_fs_names(fs_names, PAGE_SIZE, root_fs_names); |
f9259be6a init: allow mount... |
544 |
|
6e7c1770a fs: simplify get_... |
545 546 |
for (i = 0, fstype = fs_names; i < num_fs; i++, fstype += strlen(fstype) + 1) { |
b51593c4c init/do_mounts.c:... |
547 548 |
if (!*fstype) continue; |
f9259be6a init: allow mount... |
549 550 551 552 553 554 |
if (!fs_is_nodev(fstype)) continue; err = do_mount_root(root_device_name, fstype, root_mountflags, root_mount_data); if (!err) break; |
f9259be6a init: allow mount... |
555 556 557 558 559 |
} free_page((unsigned long)fs_names); return err; } |
1da177e4c Linux-2.6.12-rc2 |
560 561 562 |
void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS |
377485f62 init: don't try m... |
563 |
if (ROOT_DEV == Root_NFS) { |
c8376994c initrd: remove su... |
564 565 566 567 |
if (!mount_nfs_root()) printk(KERN_ERR "VFS: Unable to mount root fs via NFS. "); return; |
1da177e4c Linux-2.6.12-rc2 |
568 569 |
} #endif |
8902dd526 init: Support mou... |
570 571 |
#ifdef CONFIG_CIFS_ROOT if (ROOT_DEV == Root_CIFS) { |
c8376994c initrd: remove su... |
572 573 574 575 |
if (!mount_cifs_root()) printk(KERN_ERR "VFS: Unable to mount root fs via SMB. "); return; |
1da177e4c Linux-2.6.12-rc2 |
576 577 |
} #endif |
f9259be6a init: allow mount... |
578 579 580 581 |
if (ROOT_DEV == 0 && root_device_name && root_fs_names) { if (mount_nodev_root() == 0) return; } |
9361401eb [PATCH] BLOCK: Ma... |
582 |
#ifdef CONFIG_BLOCK |
c69e3c3a0 init/do_mounts.c:... |
583 584 585 586 587 588 589 590 |
{ int err = create_dev("/dev/root", ROOT_DEV); if (err < 0) pr_emerg("Failed to create /dev/root: %d ", err); mount_block_root("/dev/root", root_mountflags); } |
9361401eb [PATCH] BLOCK: Ma... |
591 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
592 593 594 595 596 597 598 |
} /* * Prepare the namespace - decide what/where to mount, load ramdisks, etc. */ void __init prepare_namespace(void) { |
1da177e4c Linux-2.6.12-rc2 |
599 |
if (root_delay) { |
ca75b4d87 insert missing sp... |
600 601 |
printk(KERN_INFO "Waiting %d sec before mounting root device... ", |
1da177e4c Linux-2.6.12-rc2 |
602 603 604 |
root_delay); ssleep(root_delay); } |
216773a78 Consolidate drive... |
605 606 607 608 609 610 611 612 |
/* * wait for the known devices to complete their probing * * Note: this is a potential source of long boot delays. * For example, it is not atypical to wait 5 seconds here * for the touchpad of a laptop to initialize. */ wait_for_device_probe(); |
d779249ed Driver Core: add ... |
613 |
|
1da177e4c Linux-2.6.12-rc2 |
614 615 616 617 |
md_run_setup(); if (saved_root_name[0]) { root_device_name = saved_root_name; |
2d62f4885 do_mounts: allow ... |
618 619 |
if (!strncmp(root_device_name, "mtd", 3) || !strncmp(root_device_name, "ubi", 3)) { |
e9482b437 [MTD] Allow alter... |
620 621 622 |
mount_block_root(root_device_name, root_mountflags); goto out; } |
1da177e4c Linux-2.6.12-rc2 |
623 624 625 626 |
ROOT_DEV = name_to_dev_t(root_device_name); if (strncmp(root_device_name, "/dev/", 5) == 0) root_device_name += 5; } |
1da177e4c Linux-2.6.12-rc2 |
627 628 |
if (initrd_load()) goto out; |
cc1ed7542 init: wait for as... |
629 630 631 632 633 634 635 |
/* wait for any asynchronous scanning to complete */ if ((ROOT_DEV == 0) && root_wait) { printk(KERN_INFO "Waiting for root device %s... ", saved_root_name); while (driver_probe_done() != 0 || (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) |
39a0e975c init: reduce root... |
636 |
msleep(5); |
216773a78 Consolidate drive... |
637 |
async_synchronize_full(); |
cc1ed7542 init: wait for as... |
638 |
} |
1da177e4c Linux-2.6.12-rc2 |
639 640 |
mount_root(); out: |
5e787dbf6 devtmpfs: use do_... |
641 |
devtmpfs_mount(); |
c60166f04 init: add an init... |
642 |
init_mount(".", "/", NULL, MS_MOVE, NULL); |
4b7ca5014 init: add an init... |
643 |
init_chroot("."); |
1da177e4c Linux-2.6.12-rc2 |
644 |
} |
57f150a58 initmpfs: move ro... |
645 |
|
6e19eded3 initmpfs: use ini... |
646 |
static bool is_tmpfs; |
f32356261 vfs: Convert ramf... |
647 |
static int rootfs_init_fs_context(struct fs_context *fc) |
57f150a58 initmpfs: move ro... |
648 |
{ |
6e19eded3 initmpfs: use ini... |
649 |
if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) |
f32356261 vfs: Convert ramf... |
650 |
return shmem_init_fs_context(fc); |
6e19eded3 initmpfs: use ini... |
651 |
|
f32356261 vfs: Convert ramf... |
652 |
return ramfs_init_fs_context(fc); |
57f150a58 initmpfs: move ro... |
653 |
} |
fd3e007f6 don't bother with... |
654 |
struct file_system_type rootfs_fs_type = { |
57f150a58 initmpfs: move ro... |
655 |
.name = "rootfs", |
f32356261 vfs: Convert ramf... |
656 |
.init_fs_context = rootfs_init_fs_context, |
57f150a58 initmpfs: move ro... |
657 658 |
.kill_sb = kill_litter_super, }; |
037f11b47 mnt_init(): call ... |
659 |
void __init init_rootfs(void) |
57f150a58 initmpfs: move ro... |
660 |
{ |
6e19eded3 initmpfs: use ini... |
661 |
if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && |
037f11b47 mnt_init(): call ... |
662 |
(!root_fs_names || strstr(root_fs_names, "tmpfs"))) |
6e19eded3 initmpfs: use ini... |
663 |
is_tmpfs = true; |
57f150a58 initmpfs: move ro... |
664 |
} |