diff options
Diffstat (limited to 'fs/cramfs/inode.c')
-rw-r--r-- | fs/cramfs/inode.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 4d1d8b7761ed..d12ea28836a5 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
25 | #include <linux/mtd/mtd.h> | 25 | #include <linux/mtd/mtd.h> |
26 | #include <linux/mtd/super.h> | 26 | #include <linux/mtd/super.h> |
27 | #include <linux/fs_context.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/vfs.h> | 29 | #include <linux/vfs.h> |
29 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
@@ -506,18 +507,19 @@ static void cramfs_kill_sb(struct super_block *sb) | |||
506 | kfree(sbi); | 507 | kfree(sbi); |
507 | } | 508 | } |
508 | 509 | ||
509 | static int cramfs_remount(struct super_block *sb, int *flags, char *data) | 510 | static int cramfs_reconfigure(struct fs_context *fc) |
510 | { | 511 | { |
511 | sync_filesystem(sb); | 512 | sync_filesystem(fc->root->d_sb); |
512 | *flags |= SB_RDONLY; | 513 | fc->sb_flags |= SB_RDONLY; |
513 | return 0; | 514 | return 0; |
514 | } | 515 | } |
515 | 516 | ||
516 | static int cramfs_read_super(struct super_block *sb, | 517 | static int cramfs_read_super(struct super_block *sb, struct fs_context *fc, |
517 | struct cramfs_super *super, int silent) | 518 | struct cramfs_super *super) |
518 | { | 519 | { |
519 | struct cramfs_sb_info *sbi = CRAMFS_SB(sb); | 520 | struct cramfs_sb_info *sbi = CRAMFS_SB(sb); |
520 | unsigned long root_offset; | 521 | unsigned long root_offset; |
522 | bool silent = fc->sb_flags & SB_SILENT; | ||
521 | 523 | ||
522 | /* We don't know the real size yet */ | 524 | /* We don't know the real size yet */ |
523 | sbi->size = PAGE_SIZE; | 525 | sbi->size = PAGE_SIZE; |
@@ -532,7 +534,7 @@ static int cramfs_read_super(struct super_block *sb, | |||
532 | /* check for wrong endianness */ | 534 | /* check for wrong endianness */ |
533 | if (super->magic == CRAMFS_MAGIC_WEND) { | 535 | if (super->magic == CRAMFS_MAGIC_WEND) { |
534 | if (!silent) | 536 | if (!silent) |
535 | pr_err("wrong endianness\n"); | 537 | errorf(fc, "cramfs: wrong endianness"); |
536 | return -EINVAL; | 538 | return -EINVAL; |
537 | } | 539 | } |
538 | 540 | ||
@@ -544,22 +546,22 @@ static int cramfs_read_super(struct super_block *sb, | |||
544 | mutex_unlock(&read_mutex); | 546 | mutex_unlock(&read_mutex); |
545 | if (super->magic != CRAMFS_MAGIC) { | 547 | if (super->magic != CRAMFS_MAGIC) { |
546 | if (super->magic == CRAMFS_MAGIC_WEND && !silent) | 548 | if (super->magic == CRAMFS_MAGIC_WEND && !silent) |
547 | pr_err("wrong endianness\n"); | 549 | errorf(fc, "cramfs: wrong endianness"); |
548 | else if (!silent) | 550 | else if (!silent) |
549 | pr_err("wrong magic\n"); | 551 | errorf(fc, "cramfs: wrong magic"); |
550 | return -EINVAL; | 552 | return -EINVAL; |
551 | } | 553 | } |
552 | } | 554 | } |
553 | 555 | ||
554 | /* get feature flags first */ | 556 | /* get feature flags first */ |
555 | if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { | 557 | if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { |
556 | pr_err("unsupported filesystem features\n"); | 558 | errorf(fc, "cramfs: unsupported filesystem features"); |
557 | return -EINVAL; | 559 | return -EINVAL; |
558 | } | 560 | } |
559 | 561 | ||
560 | /* Check that the root inode is in a sane state */ | 562 | /* Check that the root inode is in a sane state */ |
561 | if (!S_ISDIR(super->root.mode)) { | 563 | if (!S_ISDIR(super->root.mode)) { |
562 | pr_err("root is not a directory\n"); | 564 | errorf(fc, "cramfs: root is not a directory"); |
563 | return -EINVAL; | 565 | return -EINVAL; |
564 | } | 566 | } |
565 | /* correct strange, hard-coded permissions of mkcramfs */ | 567 | /* correct strange, hard-coded permissions of mkcramfs */ |
@@ -578,12 +580,12 @@ static int cramfs_read_super(struct super_block *sb, | |||
578 | sbi->magic = super->magic; | 580 | sbi->magic = super->magic; |
579 | sbi->flags = super->flags; | 581 | sbi->flags = super->flags; |
580 | if (root_offset == 0) | 582 | if (root_offset == 0) |
581 | pr_info("empty filesystem"); | 583 | infof(fc, "cramfs: empty filesystem"); |
582 | else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && | 584 | else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && |
583 | ((root_offset != sizeof(struct cramfs_super)) && | 585 | ((root_offset != sizeof(struct cramfs_super)) && |
584 | (root_offset != 512 + sizeof(struct cramfs_super)))) | 586 | (root_offset != 512 + sizeof(struct cramfs_super)))) |
585 | { | 587 | { |
586 | pr_err("bad root offset %lu\n", root_offset); | 588 | errorf(fc, "cramfs: bad root offset %lu", root_offset); |
587 | return -EINVAL; | 589 | return -EINVAL; |
588 | } | 590 | } |
589 | 591 | ||
@@ -609,8 +611,7 @@ static int cramfs_finalize_super(struct super_block *sb, | |||
609 | return 0; | 611 | return 0; |
610 | } | 612 | } |
611 | 613 | ||
612 | static int cramfs_blkdev_fill_super(struct super_block *sb, void *data, | 614 | static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *fc) |
613 | int silent) | ||
614 | { | 615 | { |
615 | struct cramfs_sb_info *sbi; | 616 | struct cramfs_sb_info *sbi; |
616 | struct cramfs_super super; | 617 | struct cramfs_super super; |
@@ -625,14 +626,13 @@ static int cramfs_blkdev_fill_super(struct super_block *sb, void *data, | |||
625 | for (i = 0; i < READ_BUFFERS; i++) | 626 | for (i = 0; i < READ_BUFFERS; i++) |
626 | buffer_blocknr[i] = -1; | 627 | buffer_blocknr[i] = -1; |
627 | 628 | ||
628 | err = cramfs_read_super(sb, &super, silent); | 629 | err = cramfs_read_super(sb, fc, &super); |
629 | if (err) | 630 | if (err) |
630 | return err; | 631 | return err; |
631 | return cramfs_finalize_super(sb, &super.root); | 632 | return cramfs_finalize_super(sb, &super.root); |
632 | } | 633 | } |
633 | 634 | ||
634 | static int cramfs_mtd_fill_super(struct super_block *sb, void *data, | 635 | static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc) |
635 | int silent) | ||
636 | { | 636 | { |
637 | struct cramfs_sb_info *sbi; | 637 | struct cramfs_sb_info *sbi; |
638 | struct cramfs_super super; | 638 | struct cramfs_super super; |
@@ -654,7 +654,7 @@ static int cramfs_mtd_fill_super(struct super_block *sb, void *data, | |||
654 | 654 | ||
655 | pr_info("checking physical address %pap for linear cramfs image\n", | 655 | pr_info("checking physical address %pap for linear cramfs image\n", |
656 | &sbi->linear_phys_addr); | 656 | &sbi->linear_phys_addr); |
657 | err = cramfs_read_super(sb, &super, silent); | 657 | err = cramfs_read_super(sb, fc, &super); |
658 | if (err) | 658 | if (err) |
659 | return err; | 659 | return err; |
660 | 660 | ||
@@ -949,32 +949,41 @@ static const struct inode_operations cramfs_dir_inode_operations = { | |||
949 | }; | 949 | }; |
950 | 950 | ||
951 | static const struct super_operations cramfs_ops = { | 951 | static const struct super_operations cramfs_ops = { |
952 | .remount_fs = cramfs_remount, | ||
953 | .statfs = cramfs_statfs, | 952 | .statfs = cramfs_statfs, |
954 | }; | 953 | }; |
955 | 954 | ||
956 | static struct dentry *cramfs_mount(struct file_system_type *fs_type, int flags, | 955 | static int cramfs_get_tree(struct fs_context *fc) |
957 | const char *dev_name, void *data) | ||
958 | { | 956 | { |
959 | struct dentry *ret = ERR_PTR(-ENOPROTOOPT); | 957 | int ret = -ENOPROTOOPT; |
960 | 958 | ||
961 | if (IS_ENABLED(CONFIG_CRAMFS_MTD)) { | 959 | if (IS_ENABLED(CONFIG_CRAMFS_MTD)) { |
962 | ret = mount_mtd(fs_type, flags, dev_name, data, | 960 | ret = get_tree_mtd(fc, cramfs_mtd_fill_super); |
963 | cramfs_mtd_fill_super); | 961 | if (ret < 0) |
964 | if (!IS_ERR(ret)) | ||
965 | return ret; | 962 | return ret; |
966 | } | 963 | } |
967 | if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) { | 964 | if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) |
968 | ret = mount_bdev(fs_type, flags, dev_name, data, | 965 | ret = get_tree_bdev(fc, cramfs_blkdev_fill_super); |
969 | cramfs_blkdev_fill_super); | ||
970 | } | ||
971 | return ret; | 966 | return ret; |
972 | } | 967 | } |
973 | 968 | ||
969 | static const struct fs_context_operations cramfs_context_ops = { | ||
970 | .get_tree = cramfs_get_tree, | ||
971 | .reconfigure = cramfs_reconfigure, | ||
972 | }; | ||
973 | |||
974 | /* | ||
975 | * Set up the filesystem mount context. | ||
976 | */ | ||
977 | static int cramfs_init_fs_context(struct fs_context *fc) | ||
978 | { | ||
979 | fc->ops = &cramfs_context_ops; | ||
980 | return 0; | ||
981 | } | ||
982 | |||
974 | static struct file_system_type cramfs_fs_type = { | 983 | static struct file_system_type cramfs_fs_type = { |
975 | .owner = THIS_MODULE, | 984 | .owner = THIS_MODULE, |
976 | .name = "cramfs", | 985 | .name = "cramfs", |
977 | .mount = cramfs_mount, | 986 | .init_fs_context = cramfs_init_fs_context, |
978 | .kill_sb = cramfs_kill_sb, | 987 | .kill_sb = cramfs_kill_sb, |
979 | .fs_flags = FS_REQUIRES_DEV, | 988 | .fs_flags = FS_REQUIRES_DEV, |
980 | }; | 989 | }; |