diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 2edfc039f098..0ac712efcdf2 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -159,7 +159,7 @@ enum { | |||
159 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, | 159 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, |
160 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, | 160 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, |
161 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, | 161 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, |
162 | Opt_enospc_debug, Opt_err, | 162 | Opt_enospc_debug, Opt_subvolrootid, Opt_err, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static match_table_t tokens = { | 165 | static match_table_t tokens = { |
@@ -189,6 +189,7 @@ static match_table_t tokens = { | |||
189 | {Opt_clear_cache, "clear_cache"}, | 189 | {Opt_clear_cache, "clear_cache"}, |
190 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, | 190 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, |
191 | {Opt_enospc_debug, "enospc_debug"}, | 191 | {Opt_enospc_debug, "enospc_debug"}, |
192 | {Opt_subvolrootid, "subvolrootid=%d"}, | ||
192 | {Opt_err, NULL}, | 193 | {Opt_err, NULL}, |
193 | }; | 194 | }; |
194 | 195 | ||
@@ -232,6 +233,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
232 | break; | 233 | break; |
233 | case Opt_subvol: | 234 | case Opt_subvol: |
234 | case Opt_subvolid: | 235 | case Opt_subvolid: |
236 | case Opt_subvolrootid: | ||
235 | case Opt_device: | 237 | case Opt_device: |
236 | /* | 238 | /* |
237 | * These are parsed by btrfs_parse_early_options | 239 | * These are parsed by btrfs_parse_early_options |
@@ -388,7 +390,7 @@ out: | |||
388 | */ | 390 | */ |
389 | static int btrfs_parse_early_options(const char *options, fmode_t flags, | 391 | static int btrfs_parse_early_options(const char *options, fmode_t flags, |
390 | void *holder, char **subvol_name, u64 *subvol_objectid, | 392 | void *holder, char **subvol_name, u64 *subvol_objectid, |
391 | struct btrfs_fs_devices **fs_devices) | 393 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) |
392 | { | 394 | { |
393 | substring_t args[MAX_OPT_ARGS]; | 395 | substring_t args[MAX_OPT_ARGS]; |
394 | char *opts, *orig, *p; | 396 | char *opts, *orig, *p; |
@@ -429,6 +431,18 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
429 | *subvol_objectid = intarg; | 431 | *subvol_objectid = intarg; |
430 | } | 432 | } |
431 | break; | 433 | break; |
434 | case Opt_subvolrootid: | ||
435 | intarg = 0; | ||
436 | error = match_int(&args[0], &intarg); | ||
437 | if (!error) { | ||
438 | /* we want the original fs_tree */ | ||
439 | if (!intarg) | ||
440 | *subvol_rootid = | ||
441 | BTRFS_FS_TREE_OBJECTID; | ||
442 | else | ||
443 | *subvol_rootid = intarg; | ||
444 | } | ||
445 | break; | ||
432 | case Opt_device: | 446 | case Opt_device: |
433 | error = btrfs_scan_one_device(match_strdup(&args[0]), | 447 | error = btrfs_scan_one_device(match_strdup(&args[0]), |
434 | flags, holder, fs_devices); | 448 | flags, holder, fs_devices); |
@@ -644,6 +658,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
644 | { | 658 | { |
645 | struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); | 659 | struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); |
646 | struct btrfs_fs_info *info = root->fs_info; | 660 | struct btrfs_fs_info *info = root->fs_info; |
661 | char *compress_type; | ||
647 | 662 | ||
648 | if (btrfs_test_opt(root, DEGRADED)) | 663 | if (btrfs_test_opt(root, DEGRADED)) |
649 | seq_puts(seq, ",degraded"); | 664 | seq_puts(seq, ",degraded"); |
@@ -662,8 +677,16 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
662 | if (info->thread_pool_size != min_t(unsigned long, | 677 | if (info->thread_pool_size != min_t(unsigned long, |
663 | num_online_cpus() + 2, 8)) | 678 | num_online_cpus() + 2, 8)) |
664 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); | 679 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); |
665 | if (btrfs_test_opt(root, COMPRESS)) | 680 | if (btrfs_test_opt(root, COMPRESS)) { |
666 | seq_puts(seq, ",compress"); | 681 | if (info->compress_type == BTRFS_COMPRESS_ZLIB) |
682 | compress_type = "zlib"; | ||
683 | else | ||
684 | compress_type = "lzo"; | ||
685 | if (btrfs_test_opt(root, FORCE_COMPRESS)) | ||
686 | seq_printf(seq, ",compress-force=%s", compress_type); | ||
687 | else | ||
688 | seq_printf(seq, ",compress=%s", compress_type); | ||
689 | } | ||
667 | if (btrfs_test_opt(root, NOSSD)) | 690 | if (btrfs_test_opt(root, NOSSD)) |
668 | seq_puts(seq, ",nossd"); | 691 | seq_puts(seq, ",nossd"); |
669 | if (btrfs_test_opt(root, SSD_SPREAD)) | 692 | if (btrfs_test_opt(root, SSD_SPREAD)) |
@@ -678,6 +701,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
678 | seq_puts(seq, ",discard"); | 701 | seq_puts(seq, ",discard"); |
679 | if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) | 702 | if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) |
680 | seq_puts(seq, ",noacl"); | 703 | seq_puts(seq, ",noacl"); |
704 | if (btrfs_test_opt(root, SPACE_CACHE)) | ||
705 | seq_puts(seq, ",space_cache"); | ||
706 | if (btrfs_test_opt(root, CLEAR_CACHE)) | ||
707 | seq_puts(seq, ",clear_cache"); | ||
708 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | ||
709 | seq_puts(seq, ",user_subvol_rm_allowed"); | ||
681 | return 0; | 710 | return 0; |
682 | } | 711 | } |
683 | 712 | ||
@@ -721,6 +750,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
721 | fmode_t mode = FMODE_READ; | 750 | fmode_t mode = FMODE_READ; |
722 | char *subvol_name = NULL; | 751 | char *subvol_name = NULL; |
723 | u64 subvol_objectid = 0; | 752 | u64 subvol_objectid = 0; |
753 | u64 subvol_rootid = 0; | ||
724 | int error = 0; | 754 | int error = 0; |
725 | 755 | ||
726 | if (!(flags & MS_RDONLY)) | 756 | if (!(flags & MS_RDONLY)) |
@@ -728,7 +758,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
728 | 758 | ||
729 | error = btrfs_parse_early_options(data, mode, fs_type, | 759 | error = btrfs_parse_early_options(data, mode, fs_type, |
730 | &subvol_name, &subvol_objectid, | 760 | &subvol_name, &subvol_objectid, |
731 | &fs_devices); | 761 | &subvol_rootid, &fs_devices); |
732 | if (error) | 762 | if (error) |
733 | return ERR_PTR(error); | 763 | return ERR_PTR(error); |
734 | 764 | ||
@@ -792,15 +822,17 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
792 | s->s_flags |= MS_ACTIVE; | 822 | s->s_flags |= MS_ACTIVE; |
793 | } | 823 | } |
794 | 824 | ||
795 | root = get_default_root(s, subvol_objectid); | ||
796 | if (IS_ERR(root)) { | ||
797 | error = PTR_ERR(root); | ||
798 | deactivate_locked_super(s); | ||
799 | goto error_free_subvol_name; | ||
800 | } | ||
801 | /* if they gave us a subvolume name bind mount into that */ | 825 | /* if they gave us a subvolume name bind mount into that */ |
802 | if (strcmp(subvol_name, ".")) { | 826 | if (strcmp(subvol_name, ".")) { |
803 | struct dentry *new_root; | 827 | struct dentry *new_root; |
828 | |||
829 | root = get_default_root(s, subvol_rootid); | ||
830 | if (IS_ERR(root)) { | ||
831 | error = PTR_ERR(root); | ||
832 | deactivate_locked_super(s); | ||
833 | goto error_free_subvol_name; | ||
834 | } | ||
835 | |||
804 | mutex_lock(&root->d_inode->i_mutex); | 836 | mutex_lock(&root->d_inode->i_mutex); |
805 | new_root = lookup_one_len(subvol_name, root, | 837 | new_root = lookup_one_len(subvol_name, root, |
806 | strlen(subvol_name)); | 838 | strlen(subvol_name)); |
@@ -821,6 +853,13 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
821 | } | 853 | } |
822 | dput(root); | 854 | dput(root); |
823 | root = new_root; | 855 | root = new_root; |
856 | } else { | ||
857 | root = get_default_root(s, subvol_objectid); | ||
858 | if (IS_ERR(root)) { | ||
859 | error = PTR_ERR(root); | ||
860 | deactivate_locked_super(s); | ||
861 | goto error_free_subvol_name; | ||
862 | } | ||
824 | } | 863 | } |
825 | 864 | ||
826 | kfree(subvol_name); | 865 | kfree(subvol_name); |