| .. | .. |
|---|
| 24 | 24 | #include <linux/blkdev.h> |
|---|
| 25 | 25 | #include <linux/mtd/mtd.h> |
|---|
| 26 | 26 | #include <linux/mtd/super.h> |
|---|
| 27 | +#include <linux/fs_context.h> |
|---|
| 27 | 28 | #include <linux/slab.h> |
|---|
| 28 | 29 | #include <linux/vfs.h> |
|---|
| 29 | 30 | #include <linux/mutex.h> |
|---|
| .. | .. |
|---|
| 419 | 420 | int i; |
|---|
| 420 | 421 | vma->vm_flags |= VM_MIXEDMAP; |
|---|
| 421 | 422 | for (i = 0; i < pages && !ret; i++) { |
|---|
| 423 | + vm_fault_t vmf; |
|---|
| 422 | 424 | unsigned long off = i * PAGE_SIZE; |
|---|
| 423 | 425 | pfn_t pfn = phys_to_pfn_t(address + off, PFN_DEV); |
|---|
| 424 | | - ret = vm_insert_mixed(vma, vma->vm_start + off, pfn); |
|---|
| 426 | + vmf = vmf_insert_mixed(vma, vma->vm_start + off, pfn); |
|---|
| 427 | + if (vmf & VM_FAULT_ERROR) |
|---|
| 428 | + ret = vm_fault_to_errno(vmf, 0); |
|---|
| 425 | 429 | } |
|---|
| 426 | 430 | } |
|---|
| 427 | 431 | |
|---|
| .. | .. |
|---|
| 503 | 507 | kfree(sbi); |
|---|
| 504 | 508 | } |
|---|
| 505 | 509 | |
|---|
| 506 | | -static int cramfs_remount(struct super_block *sb, int *flags, char *data) |
|---|
| 510 | +static int cramfs_reconfigure(struct fs_context *fc) |
|---|
| 507 | 511 | { |
|---|
| 508 | | - sync_filesystem(sb); |
|---|
| 509 | | - *flags |= SB_RDONLY; |
|---|
| 512 | + sync_filesystem(fc->root->d_sb); |
|---|
| 513 | + fc->sb_flags |= SB_RDONLY; |
|---|
| 510 | 514 | return 0; |
|---|
| 511 | 515 | } |
|---|
| 512 | 516 | |
|---|
| 513 | | -static int cramfs_read_super(struct super_block *sb, |
|---|
| 514 | | - struct cramfs_super *super, int silent) |
|---|
| 517 | +static int cramfs_read_super(struct super_block *sb, struct fs_context *fc, |
|---|
| 518 | + struct cramfs_super *super) |
|---|
| 515 | 519 | { |
|---|
| 516 | 520 | struct cramfs_sb_info *sbi = CRAMFS_SB(sb); |
|---|
| 517 | 521 | unsigned long root_offset; |
|---|
| 522 | + bool silent = fc->sb_flags & SB_SILENT; |
|---|
| 518 | 523 | |
|---|
| 519 | 524 | /* We don't know the real size yet */ |
|---|
| 520 | 525 | sbi->size = PAGE_SIZE; |
|---|
| .. | .. |
|---|
| 529 | 534 | /* check for wrong endianness */ |
|---|
| 530 | 535 | if (super->magic == CRAMFS_MAGIC_WEND) { |
|---|
| 531 | 536 | if (!silent) |
|---|
| 532 | | - pr_err("wrong endianness\n"); |
|---|
| 537 | + errorfc(fc, "wrong endianness"); |
|---|
| 533 | 538 | return -EINVAL; |
|---|
| 534 | 539 | } |
|---|
| 535 | 540 | |
|---|
| .. | .. |
|---|
| 541 | 546 | mutex_unlock(&read_mutex); |
|---|
| 542 | 547 | if (super->magic != CRAMFS_MAGIC) { |
|---|
| 543 | 548 | if (super->magic == CRAMFS_MAGIC_WEND && !silent) |
|---|
| 544 | | - pr_err("wrong endianness\n"); |
|---|
| 549 | + errorfc(fc, "wrong endianness"); |
|---|
| 545 | 550 | else if (!silent) |
|---|
| 546 | | - pr_err("wrong magic\n"); |
|---|
| 551 | + errorfc(fc, "wrong magic"); |
|---|
| 547 | 552 | return -EINVAL; |
|---|
| 548 | 553 | } |
|---|
| 549 | 554 | } |
|---|
| 550 | 555 | |
|---|
| 551 | 556 | /* get feature flags first */ |
|---|
| 552 | 557 | if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { |
|---|
| 553 | | - pr_err("unsupported filesystem features\n"); |
|---|
| 558 | + errorfc(fc, "unsupported filesystem features"); |
|---|
| 554 | 559 | return -EINVAL; |
|---|
| 555 | 560 | } |
|---|
| 556 | 561 | |
|---|
| 557 | 562 | /* Check that the root inode is in a sane state */ |
|---|
| 558 | 563 | if (!S_ISDIR(super->root.mode)) { |
|---|
| 559 | | - pr_err("root is not a directory\n"); |
|---|
| 564 | + errorfc(fc, "root is not a directory"); |
|---|
| 560 | 565 | return -EINVAL; |
|---|
| 561 | 566 | } |
|---|
| 562 | 567 | /* correct strange, hard-coded permissions of mkcramfs */ |
|---|
| .. | .. |
|---|
| 575 | 580 | sbi->magic = super->magic; |
|---|
| 576 | 581 | sbi->flags = super->flags; |
|---|
| 577 | 582 | if (root_offset == 0) |
|---|
| 578 | | - pr_info("empty filesystem"); |
|---|
| 583 | + infofc(fc, "empty filesystem"); |
|---|
| 579 | 584 | else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && |
|---|
| 580 | 585 | ((root_offset != sizeof(struct cramfs_super)) && |
|---|
| 581 | 586 | (root_offset != 512 + sizeof(struct cramfs_super)))) |
|---|
| 582 | 587 | { |
|---|
| 583 | | - pr_err("bad root offset %lu\n", root_offset); |
|---|
| 588 | + errorfc(fc, "bad root offset %lu", root_offset); |
|---|
| 584 | 589 | return -EINVAL; |
|---|
| 585 | 590 | } |
|---|
| 586 | 591 | |
|---|
| .. | .. |
|---|
| 594 | 599 | |
|---|
| 595 | 600 | /* Set it all up.. */ |
|---|
| 596 | 601 | sb->s_flags |= SB_RDONLY; |
|---|
| 602 | + sb->s_time_min = 0; |
|---|
| 603 | + sb->s_time_max = 0; |
|---|
| 597 | 604 | sb->s_op = &cramfs_ops; |
|---|
| 598 | 605 | root = get_cramfs_inode(sb, cramfs_root, 0); |
|---|
| 599 | 606 | if (IS_ERR(root)) |
|---|
| .. | .. |
|---|
| 604 | 611 | return 0; |
|---|
| 605 | 612 | } |
|---|
| 606 | 613 | |
|---|
| 607 | | -static int cramfs_blkdev_fill_super(struct super_block *sb, void *data, |
|---|
| 608 | | - int silent) |
|---|
| 614 | +static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *fc) |
|---|
| 609 | 615 | { |
|---|
| 610 | 616 | struct cramfs_sb_info *sbi; |
|---|
| 611 | 617 | struct cramfs_super super; |
|---|
| .. | .. |
|---|
| 620 | 626 | for (i = 0; i < READ_BUFFERS; i++) |
|---|
| 621 | 627 | buffer_blocknr[i] = -1; |
|---|
| 622 | 628 | |
|---|
| 623 | | - err = cramfs_read_super(sb, &super, silent); |
|---|
| 629 | + err = cramfs_read_super(sb, fc, &super); |
|---|
| 624 | 630 | if (err) |
|---|
| 625 | 631 | return err; |
|---|
| 626 | 632 | return cramfs_finalize_super(sb, &super.root); |
|---|
| 627 | 633 | } |
|---|
| 628 | 634 | |
|---|
| 629 | | -static int cramfs_mtd_fill_super(struct super_block *sb, void *data, |
|---|
| 630 | | - int silent) |
|---|
| 635 | +static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc) |
|---|
| 631 | 636 | { |
|---|
| 632 | 637 | struct cramfs_sb_info *sbi; |
|---|
| 633 | 638 | struct cramfs_super super; |
|---|
| .. | .. |
|---|
| 649 | 654 | |
|---|
| 650 | 655 | pr_info("checking physical address %pap for linear cramfs image\n", |
|---|
| 651 | 656 | &sbi->linear_phys_addr); |
|---|
| 652 | | - err = cramfs_read_super(sb, &super, silent); |
|---|
| 657 | + err = cramfs_read_super(sb, fc, &super); |
|---|
| 653 | 658 | if (err) |
|---|
| 654 | 659 | return err; |
|---|
| 655 | 660 | |
|---|
| .. | .. |
|---|
| 685 | 690 | buf->f_bavail = 0; |
|---|
| 686 | 691 | buf->f_files = CRAMFS_SB(sb)->files; |
|---|
| 687 | 692 | buf->f_ffree = 0; |
|---|
| 688 | | - buf->f_fsid.val[0] = (u32)id; |
|---|
| 689 | | - buf->f_fsid.val[1] = (u32)(id >> 32); |
|---|
| 693 | + buf->f_fsid = u64_to_fsid(id); |
|---|
| 690 | 694 | buf->f_namelen = CRAMFS_MAXPATHLEN; |
|---|
| 691 | 695 | return 0; |
|---|
| 692 | 696 | } |
|---|
| .. | .. |
|---|
| 870 | 874 | if (unlikely(block_start & CRAMFS_BLK_FLAG_DIRECT_PTR)) { |
|---|
| 871 | 875 | /* See comments on earlier code. */ |
|---|
| 872 | 876 | u32 prev_start = block_start; |
|---|
| 873 | | - block_start = prev_start & ~CRAMFS_BLK_FLAGS; |
|---|
| 874 | | - block_start <<= CRAMFS_BLK_DIRECT_PTR_SHIFT; |
|---|
| 877 | + block_start = prev_start & ~CRAMFS_BLK_FLAGS; |
|---|
| 878 | + block_start <<= CRAMFS_BLK_DIRECT_PTR_SHIFT; |
|---|
| 875 | 879 | if (prev_start & CRAMFS_BLK_FLAG_UNCOMPRESSED) { |
|---|
| 876 | 880 | block_start += PAGE_SIZE; |
|---|
| 877 | 881 | } else { |
|---|
| .. | .. |
|---|
| 944 | 948 | }; |
|---|
| 945 | 949 | |
|---|
| 946 | 950 | static const struct super_operations cramfs_ops = { |
|---|
| 947 | | - .remount_fs = cramfs_remount, |
|---|
| 948 | 951 | .statfs = cramfs_statfs, |
|---|
| 949 | 952 | }; |
|---|
| 950 | 953 | |
|---|
| 951 | | -static struct dentry *cramfs_mount(struct file_system_type *fs_type, int flags, |
|---|
| 952 | | - const char *dev_name, void *data) |
|---|
| 954 | +static int cramfs_get_tree(struct fs_context *fc) |
|---|
| 953 | 955 | { |
|---|
| 954 | | - struct dentry *ret = ERR_PTR(-ENOPROTOOPT); |
|---|
| 956 | + int ret = -ENOPROTOOPT; |
|---|
| 955 | 957 | |
|---|
| 956 | 958 | if (IS_ENABLED(CONFIG_CRAMFS_MTD)) { |
|---|
| 957 | | - ret = mount_mtd(fs_type, flags, dev_name, data, |
|---|
| 958 | | - cramfs_mtd_fill_super); |
|---|
| 959 | | - if (!IS_ERR(ret)) |
|---|
| 960 | | - return ret; |
|---|
| 959 | + ret = get_tree_mtd(fc, cramfs_mtd_fill_super); |
|---|
| 960 | + if (!ret) |
|---|
| 961 | + return 0; |
|---|
| 961 | 962 | } |
|---|
| 962 | | - if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) { |
|---|
| 963 | | - ret = mount_bdev(fs_type, flags, dev_name, data, |
|---|
| 964 | | - cramfs_blkdev_fill_super); |
|---|
| 965 | | - } |
|---|
| 963 | + if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) |
|---|
| 964 | + ret = get_tree_bdev(fc, cramfs_blkdev_fill_super); |
|---|
| 966 | 965 | return ret; |
|---|
| 966 | +} |
|---|
| 967 | + |
|---|
| 968 | +static const struct fs_context_operations cramfs_context_ops = { |
|---|
| 969 | + .get_tree = cramfs_get_tree, |
|---|
| 970 | + .reconfigure = cramfs_reconfigure, |
|---|
| 971 | +}; |
|---|
| 972 | + |
|---|
| 973 | +/* |
|---|
| 974 | + * Set up the filesystem mount context. |
|---|
| 975 | + */ |
|---|
| 976 | +static int cramfs_init_fs_context(struct fs_context *fc) |
|---|
| 977 | +{ |
|---|
| 978 | + fc->ops = &cramfs_context_ops; |
|---|
| 979 | + return 0; |
|---|
| 967 | 980 | } |
|---|
| 968 | 981 | |
|---|
| 969 | 982 | static struct file_system_type cramfs_fs_type = { |
|---|
| 970 | 983 | .owner = THIS_MODULE, |
|---|
| 971 | 984 | .name = "cramfs", |
|---|
| 972 | | - .mount = cramfs_mount, |
|---|
| 985 | + .init_fs_context = cramfs_init_fs_context, |
|---|
| 973 | 986 | .kill_sb = cramfs_kill_sb, |
|---|
| 974 | 987 | .fs_flags = FS_REQUIRES_DEV, |
|---|
| 975 | 988 | }; |
|---|
| .. | .. |
|---|
| 997 | 1010 | module_init(init_cramfs_fs) |
|---|
| 998 | 1011 | module_exit(exit_cramfs_fs) |
|---|
| 999 | 1012 | MODULE_LICENSE("GPL"); |
|---|
| 1013 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|