Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[deliverable/linux.git] / fs / btrfs / super.c
index 5a1bab11984dc45bae617d1b7aa25c7177d2c05e..00b8f37cc306df540989a9a888f0fb6cf0eb8a0e 100644 (file)
@@ -58,7 +58,6 @@
 #include "dev-replace.h"
 #include "free-space-cache.h"
 #include "backref.h"
-#include "sysfs.h"
 #include "tests/btrfs-tests.h"
 
 #include "qgroup.h"
@@ -304,7 +303,8 @@ enum {
        Opt_check_integrity_print_mask, Opt_fatal_errors, Opt_rescan_uuid_tree,
        Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,
        Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,
-       Opt_datasum, Opt_treelog, Opt_noinode_cache,
+       Opt_datasum, Opt_treelog, Opt_noinode_cache, Opt_usebackuproot,
+       Opt_nologreplay, Opt_norecovery,
 #ifdef CONFIG_BTRFS_DEBUG
        Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
 #endif
@@ -336,6 +336,8 @@ static const match_table_t tokens = {
        {Opt_noacl, "noacl"},
        {Opt_notreelog, "notreelog"},
        {Opt_treelog, "treelog"},
+       {Opt_nologreplay, "nologreplay"},
+       {Opt_norecovery, "norecovery"},
        {Opt_flushoncommit, "flushoncommit"},
        {Opt_noflushoncommit, "noflushoncommit"},
        {Opt_ratio, "metadata_ratio=%d"},
@@ -353,7 +355,8 @@ static const match_table_t tokens = {
        {Opt_inode_cache, "inode_cache"},
        {Opt_noinode_cache, "noinode_cache"},
        {Opt_no_space_cache, "nospace_cache"},
-       {Opt_recovery, "recovery"},
+       {Opt_recovery, "recovery"}, /* deprecated */
+       {Opt_usebackuproot, "usebackuproot"},
        {Opt_skip_balance, "skip_balance"},
        {Opt_check_integrity, "check_int"},
        {Opt_check_integrity_including_extent_data, "check_int_data"},
@@ -374,7 +377,8 @@ static const match_table_t tokens = {
  * reading in a new superblock is parsed here.
  * XXX JDM: This needs to be cleaned up for remount.
  */
-int btrfs_parse_options(struct btrfs_root *root, char *options)
+int btrfs_parse_options(struct btrfs_root *root, char *options,
+                       unsigned long new_flags)
 {
        struct btrfs_fs_info *info = root->fs_info;
        substring_t args[MAX_OPT_ARGS];
@@ -384,6 +388,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
        int ret = 0;
        char *compress_type;
        bool compress_force = false;
+       enum btrfs_compression_type saved_compress_type;
+       bool saved_compress_force;
+       int no_compress = 0;
 
        cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);
        if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE))
@@ -391,8 +398,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
        else if (cache_gen)
                btrfs_set_opt(info->mount_opt, SPACE_CACHE);
 
+       /*
+        * Even the options are empty, we still need to do extra check
+        * against new flags
+        */
        if (!options)
-               goto out;
+               goto check;
 
        /*
         * strsep changes the string, duplicate it because parse_options
@@ -463,6 +474,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        /* Fallthrough */
                case Opt_compress:
                case Opt_compress_type:
+                       saved_compress_type = btrfs_test_opt(root, COMPRESS) ?
+                               info->compress_type : BTRFS_COMPRESS_NONE;
+                       saved_compress_force =
+                               btrfs_test_opt(root, FORCE_COMPRESS);
                        if (token == Opt_compress ||
                            token == Opt_compress_force ||
                            strcmp(args[0].from, "zlib") == 0) {
@@ -471,6 +486,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                btrfs_set_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, NODATACOW);
                                btrfs_clear_opt(info->mount_opt, NODATASUM);
+                               no_compress = 0;
                        } else if (strcmp(args[0].from, "lzo") == 0) {
                                compress_type = "lzo";
                                info->compress_type = BTRFS_COMPRESS_LZO;
@@ -478,28 +494,21 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                btrfs_clear_opt(info->mount_opt, NODATACOW);
                                btrfs_clear_opt(info->mount_opt, NODATASUM);
                                btrfs_set_fs_incompat(info, COMPRESS_LZO);
-                               btrfs_sysfs_feature_update(root->fs_info,
-                                       BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO,
-                                       FEAT_INCOMPAT);
+                               no_compress = 0;
                        } else if (strncmp(args[0].from, "no", 2) == 0) {
                                compress_type = "no";
                                btrfs_clear_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                                compress_force = false;
+                               no_compress++;
                        } else {
                                ret = -EINVAL;
                                goto out;
                        }
 
                        if (compress_force) {
-                               btrfs_set_and_info(root, FORCE_COMPRESS,
-                                                  "force %s compression",
-                                                  compress_type);
+                               btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
                        } else {
-                               if (!btrfs_test_opt(root, COMPRESS))
-                                       btrfs_info(root->fs_info,
-                                                  "btrfs: use %s compression",
-                                                  compress_type);
                                /*
                                 * If we remount from compress-force=xxx to
                                 * compress=xxx, we need clear FORCE_COMPRESS
@@ -508,6 +517,17 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                 */
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                        }
+                       if ((btrfs_test_opt(root, COMPRESS) &&
+                            (info->compress_type != saved_compress_type ||
+                             compress_force != saved_compress_force)) ||
+                           (!btrfs_test_opt(root, COMPRESS) &&
+                            no_compress == 1)) {
+                               btrfs_info(root->fs_info,
+                                          "%s %s compression",
+                                          (compress_force) ? "force" : "use",
+                                          compress_type);
+                       }
+                       compress_force = false;
                        break;
                case Opt_ssd:
                        btrfs_set_and_info(root, SSD,
@@ -595,6 +615,11 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        btrfs_clear_and_info(root, NOTREELOG,
                                             "enabling tree log");
                        break;
+               case Opt_norecovery:
+               case Opt_nologreplay:
+                       btrfs_set_and_info(root, NOLOGREPLAY,
+                                          "disabling log replay at mount time");
+                       break;
                case Opt_flushoncommit:
                        btrfs_set_and_info(root, FLUSHONCOMMIT,
                                           "turning on flush-on-commit");
@@ -685,8 +710,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                                             "disabling auto defrag");
                        break;
                case Opt_recovery:
-                       btrfs_info(root->fs_info, "enabling auto recovery");
-                       btrfs_set_opt(info->mount_opt, RECOVERY);
+                       btrfs_warn(root->fs_info,
+                                  "'recovery' is deprecated, use 'usebackuproot' instead");
+               case Opt_usebackuproot:
+                       btrfs_info(root->fs_info,
+                                  "trying to use backup root at mount time");
+                       btrfs_set_opt(info->mount_opt, USEBACKUPROOT);
                        break;
                case Opt_skip_balance:
                        btrfs_set_opt(info->mount_opt, SKIP_BALANCE);
@@ -781,6 +810,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
                        break;
                }
        }
+check:
+       /*
+        * Extra check for current option against current flag
+        */
+       if (btrfs_test_opt(root, NOLOGREPLAY) && !(new_flags & MS_RDONLY)) {
+               btrfs_err(root->fs_info,
+                         "nologreplay must be used with ro mount option");
+               ret = -EINVAL;
+       }
 out:
        if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&
            !btrfs_test_opt(root, FREE_SPACE_TREE) &&
@@ -1191,6 +1229,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
                seq_puts(seq, ",ssd");
        if (btrfs_test_opt(root, NOTREELOG))
                seq_puts(seq, ",notreelog");
+       if (btrfs_test_opt(root, NOLOGREPLAY))
+               seq_puts(seq, ",nologreplay");
        if (btrfs_test_opt(root, FLUSHONCOMMIT))
                seq_puts(seq, ",flushoncommit");
        if (btrfs_test_opt(root, DISCARD))
@@ -1217,8 +1257,6 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
                seq_puts(seq, ",inode_cache");
        if (btrfs_test_opt(root, SKIP_BALANCE))
                seq_puts(seq, ",skip_balance");
-       if (btrfs_test_opt(root, RECOVERY))
-               seq_puts(seq, ",recovery");
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        if (btrfs_test_opt(root, CHECK_INTEGRITY_INCLUDING_EXTENT_DATA))
                seq_puts(seq, ",check_int_data");
@@ -1553,9 +1591,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                if ((flags ^ s->s_flags) & MS_RDONLY)
                        error = -EBUSY;
        } else {
-               char b[BDEVNAME_SIZE];
-
-               strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+               snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
                btrfs_sb(s)->bdev_holder = fs_type;
                error = btrfs_fill_super(s, fs_devices, data,
                                         flags & MS_SILENT ? 1 : 0);
@@ -1676,7 +1712,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                }
        }
 
-       ret = btrfs_parse_options(root, data);
+       ret = btrfs_parse_options(root, data, *flags);
        if (ret) {
                ret = -EINVAL;
                goto restore;
@@ -2154,6 +2190,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
                        break;
                ret = !(fs_devices->num_devices == fs_devices->total_devices);
                break;
+       case BTRFS_IOC_GET_SUPPORTED_FEATURES:
+               ret = btrfs_ioctl_get_supported_features((void __user*)arg);
+               break;
        }
 
        kfree(vol);
@@ -2252,7 +2291,7 @@ static void btrfs_interface_exit(void)
        misc_deregister(&btrfs_misc);
 }
 
-static void btrfs_print_info(void)
+static void btrfs_print_mod_info(void)
 {
        printk(KERN_INFO "Btrfs loaded"
 #ifdef CONFIG_BTRFS_DEBUG
@@ -2354,7 +2393,7 @@ static int __init init_btrfs_fs(void)
 
        btrfs_init_lockdep();
 
-       btrfs_print_info();
+       btrfs_print_mod_info();
 
        err = btrfs_run_sanity_tests();
        if (err)
This page took 0.040534 seconds and 5 git commands to generate.