Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'work.init' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull root filesystem type handling updates from Al Viro:
"Teach init/do_mounts.c to handle non-block filesystems, hopefully
preventing even more special-cased kludges (such as root=/dev/nfs,
etc)"

* 'work.init' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fs: simplify get_filesystem_list / get_all_fs_names
init: allow mounting arbitrary non-blockdevice filesystems as root
init: split get_fs_names

+83 -36
+17 -10
fs/filesystems.c
··· 209 209 } 210 210 #endif 211 211 212 - int __init get_filesystem_list(char *buf) 212 + int __init list_bdev_fs_names(char *buf, size_t size) 213 213 { 214 - int len = 0; 215 - struct file_system_type * tmp; 214 + struct file_system_type *p; 215 + size_t len; 216 + int count = 0; 216 217 217 218 read_lock(&file_systems_lock); 218 - tmp = file_systems; 219 - while (tmp && len < PAGE_SIZE - 80) { 220 - len += sprintf(buf+len, "%s\t%s\n", 221 - (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev", 222 - tmp->name); 223 - tmp = tmp->next; 219 + for (p = file_systems; p; p = p->next) { 220 + if (!(p->fs_flags & FS_REQUIRES_DEV)) 221 + continue; 222 + len = strlen(p->name) + 1; 223 + if (len > size) { 224 + pr_warn("%s: truncating file system list\n", __func__); 225 + break; 226 + } 227 + memcpy(buf, p->name, len); 228 + buf += len; 229 + size -= len; 230 + count++; 224 231 } 225 232 read_unlock(&file_systems_lock); 226 - return len; 233 + return count; 227 234 } 228 235 229 236 #ifdef CONFIG_PROC_FS
+1 -1
include/linux/fs.h
··· 3592 3592 void *buffer, size_t *lenp, loff_t *ppos); 3593 3593 int proc_nr_inodes(struct ctl_table *table, int write, 3594 3594 void *buffer, size_t *lenp, loff_t *ppos); 3595 - int __init get_filesystem_list(char *buf); 3595 + int __init list_bdev_fs_names(char *buf, size_t size); 3596 3596 3597 3597 #define __FMODE_EXEC ((__force int) FMODE_EXEC) 3598 3598 #define __FMODE_NONOTIFY ((__force int) FMODE_NONOTIFY)
+65 -25
init/do_mounts.c
··· 338 338 __setup("rootfstype=", fs_names_setup); 339 339 __setup("rootdelay=", root_delay_setup); 340 340 341 - static void __init get_fs_names(char *page) 341 + static int __init split_fs_names(char *page, char *names) 342 342 { 343 - char *s = page; 343 + int count = 0; 344 + char *p = page; 344 345 345 - if (root_fs_names) { 346 - strcpy(page, root_fs_names); 347 - while (*s++) { 348 - if (s[-1] == ',') 349 - s[-1] = '\0'; 350 - } 351 - } else { 352 - int len = get_filesystem_list(page); 353 - char *p, *next; 354 - 355 - page[len] = '\0'; 356 - for (p = page-1; p; p = next) { 357 - next = strchr(++p, '\n'); 358 - if (*p++ != '\t') 359 - continue; 360 - while ((*s++ = *p++) != '\n') 361 - ; 362 - s[-1] = '\0'; 363 - } 346 + strcpy(p, root_fs_names); 347 + while (*p++) { 348 + if (p[-1] == ',') 349 + p[-1] = '\0'; 364 350 } 365 - *s = '\0'; 351 + *p = '\0'; 352 + 353 + for (p = page; *p; p += strlen(p)+1) 354 + count++; 355 + 356 + return count; 366 357 } 367 358 368 359 static int __init do_mount_root(const char *name, const char *fs, ··· 399 408 char *fs_names = page_address(page); 400 409 char *p; 401 410 char b[BDEVNAME_SIZE]; 411 + int num_fs, i; 402 412 403 413 scnprintf(b, BDEVNAME_SIZE, "unknown-block(%u,%u)", 404 414 MAJOR(ROOT_DEV), MINOR(ROOT_DEV)); 405 - get_fs_names(fs_names); 415 + if (root_fs_names) 416 + num_fs = split_fs_names(fs_names, root_fs_names); 417 + else 418 + num_fs = list_bdev_fs_names(fs_names, PAGE_SIZE); 406 419 retry: 407 - for (p = fs_names; *p; p += strlen(p)+1) { 420 + for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) { 408 421 int err = do_mount_root(name, p, flags, root_mount_data); 409 422 switch (err) { 410 423 case 0: ··· 437 442 printk("List of all partitions:\n"); 438 443 printk_all_partitions(); 439 444 printk("No filesystem could mount root, tried: "); 440 - for (p = fs_names; *p; p += strlen(p)+1) 445 + for (i = 0, p = fs_names; i < num_fs; i++, p += strlen(p)+1) 441 446 printk(" %s", p); 442 447 printk("\n"); 443 448 panic("VFS: Unable to mount root fs on %s", b); ··· 521 526 } 522 527 #endif 523 528 529 + static bool __init fs_is_nodev(char *fstype) 530 + { 531 + struct file_system_type *fs = get_fs_type(fstype); 532 + bool ret = false; 533 + 534 + if (fs) { 535 + ret = !(fs->fs_flags & FS_REQUIRES_DEV); 536 + put_filesystem(fs); 537 + } 538 + 539 + return ret; 540 + } 541 + 542 + static int __init mount_nodev_root(void) 543 + { 544 + char *fs_names, *fstype; 545 + int err = -EINVAL; 546 + int num_fs, i; 547 + 548 + fs_names = (void *)__get_free_page(GFP_KERNEL); 549 + if (!fs_names) 550 + return -EINVAL; 551 + num_fs = split_fs_names(fs_names, root_fs_names); 552 + 553 + for (i = 0, fstype = fs_names; i < num_fs; 554 + i++, fstype += strlen(fstype) + 1) { 555 + if (!fs_is_nodev(fstype)) 556 + continue; 557 + err = do_mount_root(root_device_name, fstype, root_mountflags, 558 + root_mount_data); 559 + if (!err) 560 + break; 561 + if (err != -EACCES && err != -EINVAL) 562 + panic("VFS: Unable to mount root \"%s\" (%s), err=%d\n", 563 + root_device_name, fstype, err); 564 + } 565 + 566 + free_page((unsigned long)fs_names); 567 + return err; 568 + } 569 + 524 570 void __init mount_root(void) 525 571 { 526 572 #ifdef CONFIG_ROOT_NFS ··· 578 542 return; 579 543 } 580 544 #endif 545 + if (ROOT_DEV == 0 && root_device_name && root_fs_names) { 546 + if (mount_nodev_root() == 0) 547 + return; 548 + } 581 549 #ifdef CONFIG_BLOCK 582 550 { 583 551 int err = create_dev("/dev/root", ROOT_DEV);