Merge tag 'f2fs-for-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[linux-2.6-microblaze.git] / fs / f2fs / super.c
index f3c1511..20e56b0 100644 (file)
@@ -202,6 +202,7 @@ static match_table_t f2fs_tokens = {
        {Opt_whint, "whint_mode=%s"},
        {Opt_alloc, "alloc_mode=%s"},
        {Opt_fsync, "fsync_mode=%s"},
+       {Opt_test_dummy_encryption, "test_dummy_encryption=%s"},
        {Opt_test_dummy_encryption, "test_dummy_encryption"},
        {Opt_checkpoint_disable, "checkpoint=disable"},
        {Opt_checkpoint_disable_cap, "checkpoint=disable:%u"},
@@ -410,7 +411,52 @@ static int f2fs_check_quota_options(struct f2fs_sb_info *sbi)
 }
 #endif
 
-static int parse_options(struct super_block *sb, char *options)
+static int f2fs_set_test_dummy_encryption(struct super_block *sb,
+                                         const char *opt,
+                                         const substring_t *arg,
+                                         bool is_remount)
+{
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+#ifdef CONFIG_FS_ENCRYPTION
+       int err;
+
+       if (!f2fs_sb_has_encrypt(sbi)) {
+               f2fs_err(sbi, "Encrypt feature is off");
+               return -EINVAL;
+       }
+
+       /*
+        * This mount option is just for testing, and it's not worthwhile to
+        * implement the extra complexity (e.g. RCU protection) that would be
+        * needed to allow it to be set or changed during remount.  We do allow
+        * it to be specified during remount, but only if there is no change.
+        */
+       if (is_remount && !F2FS_OPTION(sbi).dummy_enc_ctx.ctx) {
+               f2fs_warn(sbi, "Can't set test_dummy_encryption on remount");
+               return -EINVAL;
+       }
+       err = fscrypt_set_test_dummy_encryption(
+               sb, arg, &F2FS_OPTION(sbi).dummy_enc_ctx);
+       if (err) {
+               if (err == -EEXIST)
+                       f2fs_warn(sbi,
+                                 "Can't change test_dummy_encryption on remount");
+               else if (err == -EINVAL)
+                       f2fs_warn(sbi, "Value of option \"%s\" is unrecognized",
+                                 opt);
+               else
+                       f2fs_warn(sbi, "Error processing option \"%s\" [%d]",
+                                 opt, err);
+               return -EINVAL;
+       }
+       f2fs_warn(sbi, "Test dummy encryption mode enabled");
+#else
+       f2fs_warn(sbi, "Test dummy encryption mount option ignored");
+#endif
+       return 0;
+}
+
+static int parse_options(struct super_block *sb, char *options, bool is_remount)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(sb);
        substring_t args[MAX_OPT_ARGS];
@@ -419,9 +465,7 @@ static int parse_options(struct super_block *sb, char *options)
        int arg = 0, ext_cnt;
        kuid_t uid;
        kgid_t gid;
-#ifdef CONFIG_QUOTA
        int ret;
-#endif
 
        if (!options)
                return 0;
@@ -784,17 +828,10 @@ static int parse_options(struct super_block *sb, char *options)
                        kvfree(name);
                        break;
                case Opt_test_dummy_encryption:
-#ifdef CONFIG_FS_ENCRYPTION
-                       if (!f2fs_sb_has_encrypt(sbi)) {
-                               f2fs_err(sbi, "Encrypt feature is off");
-                               return -EINVAL;
-                       }
-
-                       F2FS_OPTION(sbi).test_dummy_encryption = true;
-                       f2fs_info(sbi, "Test dummy encryption mode enabled");
-#else
-                       f2fs_info(sbi, "Test dummy encryption mount option ignored");
-#endif
+                       ret = f2fs_set_test_dummy_encryption(sb, p, &args[0],
+                                                            is_remount);
+                       if (ret)
+                               return ret;
                        break;
                case Opt_checkpoint_disable_cap_perc:
                        if (args->from && match_int(args, &arg))
@@ -1215,6 +1252,7 @@ static void f2fs_put_super(struct super_block *sb)
        for (i = 0; i < MAXQUOTAS; i++)
                kvfree(F2FS_OPTION(sbi).s_qf_names[i]);
 #endif
+       fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx);
        destroy_percpu_info(sbi);
        for (i = 0; i < NR_PAGE_TYPE; i++)
                kvfree(sbi->write_io[i]);
@@ -1549,10 +1587,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
                seq_printf(seq, ",whint_mode=%s", "user-based");
        else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
                seq_printf(seq, ",whint_mode=%s", "fs-based");
-#ifdef CONFIG_FS_ENCRYPTION
-       if (F2FS_OPTION(sbi).test_dummy_encryption)
-               seq_puts(seq, ",test_dummy_encryption");
-#endif
+
+       fscrypt_show_test_dummy_encryption(seq, ',', sbi->sb);
 
        if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_DEFAULT)
                seq_printf(seq, ",alloc_mode=%s", "default");
@@ -1581,7 +1617,6 @@ static void default_options(struct f2fs_sb_info *sbi)
        F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
        F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
        F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX;
-       F2FS_OPTION(sbi).test_dummy_encryption = false;
        F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
        F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID);
        F2FS_OPTION(sbi).compress_algorithm = COMPRESS_LZ4;
@@ -1740,7 +1775,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
        default_options(sbi);
 
        /* parse mount options */
-       err = parse_options(sb, data);
+       err = parse_options(sb, data, true);
        if (err)
                goto restore_opts;
        checkpoint_changed =
@@ -2417,9 +2452,10 @@ static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
                                ctx, len, fs_data, XATTR_CREATE);
 }
 
-static bool f2fs_dummy_context(struct inode *inode)
+static const union fscrypt_context *
+f2fs_get_dummy_context(struct super_block *sb)
 {
-       return DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(inode));
+       return F2FS_OPTION(F2FS_SB(sb)).dummy_enc_ctx.ctx;
 }
 
 static bool f2fs_has_stable_inodes(struct super_block *sb)
@@ -2438,7 +2474,7 @@ static const struct fscrypt_operations f2fs_cryptops = {
        .key_prefix             = "f2fs:",
        .get_context            = f2fs_get_context,
        .set_context            = f2fs_set_context,
-       .dummy_context          = f2fs_dummy_context,
+       .get_dummy_context      = f2fs_get_dummy_context,
        .empty_dir              = f2fs_empty_dir,
        .max_namelen            = F2FS_NAME_LEN,
        .has_stable_inodes      = f2fs_has_stable_inodes,
@@ -3373,7 +3409,7 @@ try_onemore:
                goto free_sb_buf;
        }
 
-       err = parse_options(sb, options);
+       err = parse_options(sb, options, false);
        if (err)
                goto free_options;
 
@@ -3777,6 +3813,7 @@ free_options:
        for (i = 0; i < MAXQUOTAS; i++)
                kvfree(F2FS_OPTION(sbi).s_qf_names[i]);
 #endif
+       fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx);
        kvfree(options);
 free_sb_buf:
        kvfree(raw_super);