--- /dev/null
+From 5f41fdaea63ddf96d921ab36b2af4a90ccdb5744 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 19 May 2022 13:44:37 -0700
+Subject: ext4: only allow test_dummy_encryption when supported
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 5f41fdaea63ddf96d921ab36b2af4a90ccdb5744 upstream.
+
+Make the test_dummy_encryption mount option require that the encrypt
+feature flag be already enabled on the filesystem, rather than
+automatically enabling it. Practically, this means that "-O encrypt"
+will need to be included in MKFS_OPTIONS when running xfstests with the
+test_dummy_encryption mount option. (ext4/053 also needs an update.)
+
+Moreover, as long as the preconditions for test_dummy_encryption are
+being tightened anyway, take the opportunity to start rejecting it when
+!CONFIG_FS_ENCRYPTION rather than ignoring it.
+
+The motivation for requiring the encrypt feature flag is that:
+
+- Having the filesystem auto-enable feature flags is problematic, as it
+ bypasses the usual sanity checks. The specific issue which came up
+ recently is that in kernel versions where ext4 supports casefold but
+ not encrypt+casefold (v5.1 through v5.10), the kernel will happily add
+ the encrypt flag to a filesystem that has the casefold flag, making it
+ unmountable -- but only for subsequent mounts, not the initial one.
+ This confused the casefold support detection in xfstests, causing
+ generic/556 to fail rather than be skipped.
+
+- The xfstests-bld test runners (kvm-xfstests et al.) already use the
+ required mkfs flag, so they will not be affected by this change. Only
+ users of test_dummy_encryption alone will be affected. But, this
+ option has always been for testing only, so it should be fine to
+ require that the few users of this option update their test scripts.
+
+- f2fs already requires it (for its equivalent feature flag).
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.com>
+Link: https://lore.kernel.org/r/20220519204437.61645-1-ebiggers@kernel.org
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h | 6 -----
+ fs/ext4/super.c | 60 +++++++++++++++++++++++++++++++++++---------------------
+ 2 files changed, 38 insertions(+), 28 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1440,12 +1440,6 @@ struct ext4_super_block {
+
+ #ifdef __KERNEL__
+
+-#ifdef CONFIG_FS_ENCRYPTION
+-#define DUMMY_ENCRYPTION_ENABLED(sbi) ((sbi)->s_dummy_enc_policy.policy != NULL)
+-#else
+-#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
+-#endif
+-
+ /* Number of quota types we support */
+ #define EXT4_MAXQUOTAS 3
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2428,11 +2428,12 @@ static int ext4_parse_param(struct fs_co
+ ctx->spec |= EXT4_SPEC_DUMMY_ENCRYPTION;
+ ctx->test_dummy_enc_arg = kmemdup_nul(param->string, param->size,
+ GFP_KERNEL);
++ return 0;
+ #else
+ ext4_msg(NULL, KERN_WARNING,
+- "Test dummy encryption mount option ignored");
++ "test_dummy_encryption option not supported");
++ return -EINVAL;
+ #endif
+- return 0;
+ case Opt_dax:
+ case Opt_dax_type:
+ #ifdef CONFIG_FS_DAX
+@@ -2789,12 +2790,44 @@ err_jquota_specified:
+ #endif
+ }
+
++static int ext4_check_test_dummy_encryption(const struct fs_context *fc,
++ struct super_block *sb)
++{
++#ifdef CONFIG_FS_ENCRYPTION
++ const struct ext4_fs_context *ctx = fc->fs_private;
++ const struct ext4_sb_info *sbi = EXT4_SB(sb);
++
++ if (!(ctx->spec & EXT4_SPEC_DUMMY_ENCRYPTION))
++ return 0;
++
++ if (!ext4_has_feature_encrypt(sb)) {
++ ext4_msg(NULL, KERN_WARNING,
++ "test_dummy_encryption requires encrypt feature");
++ 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 (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE &&
++ !sbi->s_dummy_enc_policy.policy) {
++ ext4_msg(NULL, KERN_WARNING,
++ "Can't set test_dummy_encryption on remount");
++ return -EINVAL;
++ }
++#endif /* CONFIG_FS_ENCRYPTION */
++ return 0;
++}
++
+ static int ext4_check_opt_consistency(struct fs_context *fc,
+ struct super_block *sb)
+ {
+ struct ext4_fs_context *ctx = fc->fs_private;
+ struct ext4_sb_info *sbi = fc->s_fs_info;
+ int is_remount = fc->purpose == FS_CONTEXT_FOR_RECONFIGURE;
++ int err;
+
+ if ((ctx->opt_flags & MOPT_NO_EXT2) && IS_EXT2_SB(sb)) {
+ ext4_msg(NULL, KERN_ERR,
+@@ -2824,20 +2857,9 @@ static int ext4_check_opt_consistency(st
+ "for blocksize < PAGE_SIZE");
+ }
+
+-#ifdef CONFIG_FS_ENCRYPTION
+- /*
+- * 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 ((ctx->spec & EXT4_SPEC_DUMMY_ENCRYPTION) &&
+- is_remount && !sbi->s_dummy_enc_policy.policy) {
+- ext4_msg(NULL, KERN_WARNING,
+- "Can't set test_dummy_encryption on remount");
+- return -1;
+- }
+-#endif
++ err = ext4_check_test_dummy_encryption(fc, sb);
++ if (err)
++ return err;
+
+ if ((ctx->spec & EXT4_SPEC_DATAJ) && is_remount) {
+ if (!sbi->s_journal) {
+@@ -5283,12 +5305,6 @@ no_journal:
+ goto failed_mount_wq;
+ }
+
+- if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
+- !ext4_has_feature_encrypt(sb)) {
+- ext4_set_feature_encrypt(sb);
+- ext4_commit_super(sb);
+- }
+-
+ /*
+ * Get the # of file system overhead blocks from the
+ * superblock if present.