aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c66
1 files changed, 55 insertions, 11 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index d39a9895d932..0ac712efcdf2 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -52,6 +52,9 @@
52#include "export.h" 52#include "export.h"
53#include "compression.h" 53#include "compression.h"
54 54
55#define CREATE_TRACE_POINTS
56#include <trace/events/btrfs.h>
57
55static const struct super_operations btrfs_super_ops; 58static const struct super_operations btrfs_super_ops;
56 59
57static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, 60static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno,
@@ -156,7 +159,7 @@ enum {
156 Opt_compress_type, Opt_compress_force, Opt_compress_force_type, 159 Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
157 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, 160 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
158 Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, 161 Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
159 Opt_enospc_debug, Opt_err, 162 Opt_enospc_debug, Opt_subvolrootid, Opt_err,
160}; 163};
161 164
162static match_table_t tokens = { 165static match_table_t tokens = {
@@ -186,6 +189,7 @@ static match_table_t tokens = {
186 {Opt_clear_cache, "clear_cache"}, 189 {Opt_clear_cache, "clear_cache"},
187 {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, 190 {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
188 {Opt_enospc_debug, "enospc_debug"}, 191 {Opt_enospc_debug, "enospc_debug"},
192 {Opt_subvolrootid, "subvolrootid=%d"},
189 {Opt_err, NULL}, 193 {Opt_err, NULL},
190}; 194};
191 195
@@ -229,6 +233,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
229 break; 233 break;
230 case Opt_subvol: 234 case Opt_subvol:
231 case Opt_subvolid: 235 case Opt_subvolid:
236 case Opt_subvolrootid:
232 case Opt_device: 237 case Opt_device:
233 /* 238 /*
234 * These are parsed by btrfs_parse_early_options 239 * These are parsed by btrfs_parse_early_options
@@ -385,7 +390,7 @@ out:
385 */ 390 */
386static int btrfs_parse_early_options(const char *options, fmode_t flags, 391static int btrfs_parse_early_options(const char *options, fmode_t flags,
387 void *holder, char **subvol_name, u64 *subvol_objectid, 392 void *holder, char **subvol_name, u64 *subvol_objectid,
388 struct btrfs_fs_devices **fs_devices) 393 u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices)
389{ 394{
390 substring_t args[MAX_OPT_ARGS]; 395 substring_t args[MAX_OPT_ARGS];
391 char *opts, *orig, *p; 396 char *opts, *orig, *p;
@@ -426,6 +431,18 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
426 *subvol_objectid = intarg; 431 *subvol_objectid = intarg;
427 } 432 }
428 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;
429 case Opt_device: 446 case Opt_device:
430 error = btrfs_scan_one_device(match_strdup(&args[0]), 447 error = btrfs_scan_one_device(match_strdup(&args[0]),
431 flags, holder, fs_devices); 448 flags, holder, fs_devices);
@@ -620,6 +637,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
620 struct btrfs_root *root = btrfs_sb(sb); 637 struct btrfs_root *root = btrfs_sb(sb);
621 int ret; 638 int ret;
622 639
640 trace_btrfs_sync_fs(wait);
641
623 if (!wait) { 642 if (!wait) {
624 filemap_flush(root->fs_info->btree_inode->i_mapping); 643 filemap_flush(root->fs_info->btree_inode->i_mapping);
625 return 0; 644 return 0;
@@ -639,6 +658,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
639{ 658{
640 struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); 659 struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
641 struct btrfs_fs_info *info = root->fs_info; 660 struct btrfs_fs_info *info = root->fs_info;
661 char *compress_type;
642 662
643 if (btrfs_test_opt(root, DEGRADED)) 663 if (btrfs_test_opt(root, DEGRADED))
644 seq_puts(seq, ",degraded"); 664 seq_puts(seq, ",degraded");
@@ -657,8 +677,16 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
657 if (info->thread_pool_size != min_t(unsigned long, 677 if (info->thread_pool_size != min_t(unsigned long,
658 num_online_cpus() + 2, 8)) 678 num_online_cpus() + 2, 8))
659 seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); 679 seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
660 if (btrfs_test_opt(root, COMPRESS)) 680 if (btrfs_test_opt(root, COMPRESS)) {
661 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 }
662 if (btrfs_test_opt(root, NOSSD)) 690 if (btrfs_test_opt(root, NOSSD))
663 seq_puts(seq, ",nossd"); 691 seq_puts(seq, ",nossd");
664 if (btrfs_test_opt(root, SSD_SPREAD)) 692 if (btrfs_test_opt(root, SSD_SPREAD))
@@ -673,6 +701,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
673 seq_puts(seq, ",discard"); 701 seq_puts(seq, ",discard");
674 if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) 702 if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
675 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");
676 return 0; 710 return 0;
677} 711}
678 712
@@ -716,6 +750,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
716 fmode_t mode = FMODE_READ; 750 fmode_t mode = FMODE_READ;
717 char *subvol_name = NULL; 751 char *subvol_name = NULL;
718 u64 subvol_objectid = 0; 752 u64 subvol_objectid = 0;
753 u64 subvol_rootid = 0;
719 int error = 0; 754 int error = 0;
720 755
721 if (!(flags & MS_RDONLY)) 756 if (!(flags & MS_RDONLY))
@@ -723,7 +758,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
723 758
724 error = btrfs_parse_early_options(data, mode, fs_type, 759 error = btrfs_parse_early_options(data, mode, fs_type,
725 &subvol_name, &subvol_objectid, 760 &subvol_name, &subvol_objectid,
726 &fs_devices); 761 &subvol_rootid, &fs_devices);
727 if (error) 762 if (error)
728 return ERR_PTR(error); 763 return ERR_PTR(error);
729 764
@@ -787,15 +822,17 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
787 s->s_flags |= MS_ACTIVE; 822 s->s_flags |= MS_ACTIVE;
788 } 823 }
789 824
790 root = get_default_root(s, subvol_objectid);
791 if (IS_ERR(root)) {
792 error = PTR_ERR(root);
793 deactivate_locked_super(s);
794 goto error_free_subvol_name;
795 }
796 /* if they gave us a subvolume name bind mount into that */ 825 /* if they gave us a subvolume name bind mount into that */
797 if (strcmp(subvol_name, ".")) { 826 if (strcmp(subvol_name, ".")) {
798 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
799 mutex_lock(&root->d_inode->i_mutex); 836 mutex_lock(&root->d_inode->i_mutex);
800 new_root = lookup_one_len(subvol_name, root, 837 new_root = lookup_one_len(subvol_name, root,
801 strlen(subvol_name)); 838 strlen(subvol_name));
@@ -816,6 +853,13 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
816 } 853 }
817 dput(root); 854 dput(root);
818 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 }
819 } 863 }
820 864
821 kfree(subvol_name); 865 kfree(subvol_name);