diff options
author | Daniel Rosenberg <drosen@google.com> | 2020-06-10 21:18:44 -0700 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2021-01-27 23:35:09 -0500 |
commit | b437e1ed5f7446b832e25ce9ca1f0ef89b7329ed (patch) | |
tree | 0433de8d30d5fbe5e9b60d87abdc51d6e98d4732 | |
parent | 0ea0a9e79047604a205dd3a17448271a2e25b615 (diff) | |
download | e2fsprogs-b437e1ed5f7446b832e25ce9ca1f0ef89b7329ed.tar.gz |
AOSP: ANDROID: tune2fs: Allow setting the casefold feature
This allows tune2fs to enable casefolding on an existing filesystem.
At the moment, casefolding is incompatible with encryption.
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Google-Bug-Id: 138322712
Test: Create fs without casefold and enable it via tune2fs
Change-Id: Ic9ed63180ef28c36e083cee85ade432e4bfcc654
From AOSP commit: eb5b168decac07058e90ead191350be80c75aff4
-rw-r--r-- | misc/tune2fs.8.in | 29 | ||||
-rw-r--r-- | misc/tune2fs.c | 97 |
2 files changed, 119 insertions, 7 deletions
diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in index 3cf1f5eda..7b0776a94 100644 --- a/misc/tune2fs.8.in +++ b/misc/tune2fs.8.in @@ -218,6 +218,30 @@ directories. Valid algorithms accepted are: and .IR tea . .TP +.BI encoding= encoding-name +Enable the +.I casefold +feature in the super block and set +.I encoding-name +as the encoding to be used. If +.I encoding-name +is not specified, utf8 is used. The encoding cannot be altered if casefold +was previously enabled. +.TP +.BI encoding_flags= encoding-flags +Define parameters for file name character encoding operations. If a +flag is not changed using this parameter, its default value is used. +.I encoding-flags +should be a comma-separated lists of flags to be enabled. The flags cannot be +altered if casefold was previously enabled. + +The only flag that can be set right now is +.I strict +which means that invalid strings should be rejected by the file system. +In the default configuration, the +.I strict +flag is disabled. +.TP .BI mount_opts= mount_option_string Set a set of default mount options which will be used when the file system is mounted. Unlike the bitmask-based default mount options which @@ -542,6 +566,11 @@ The following filesystem features can be set or cleared using .B 64bit Enable the file system to be larger than 2^32 blocks. .TP +.B casefold +Enable support for file system level casefolding. +.B Tune2fs +currently only supports setting this filesystem feature. +.TP .B dir_index Use hashed b-trees to speed up lookups for large directories. .TP diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 48b8ce857..15fa36f28 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -101,6 +101,7 @@ static int rewrite_checksums; static int feature_64bit; static int fsck_requested; static char *undo_file; +int enabling_casefold; int journal_size, journal_flags; char *journal_device; @@ -159,7 +160,8 @@ static __u32 ok_features[3] = { EXT4_FEATURE_INCOMPAT_64BIT | EXT4_FEATURE_INCOMPAT_ENCRYPT | EXT4_FEATURE_INCOMPAT_CSUM_SEED | - EXT4_FEATURE_INCOMPAT_LARGEDIR, + EXT4_FEATURE_INCOMPAT_LARGEDIR | + EXT4_FEATURE_INCOMPAT_CASEFOLD, /* R/O compat */ EXT2_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_HUGE_FILE| @@ -1429,6 +1431,23 @@ mmp_error: EXT4_ENCRYPTION_MODE_AES_256_CTS; } + if (FEATURE_ON(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD)) { + if (ext2fs_has_feature_encrypt(sb)) { + fputs(_("Cannot enable casefold feature on filesystems " + "with the encrypt feature enabled.\n"), + stderr); + return 1; + } + if (mount_flags & EXT2_MF_MOUNTED) { + fputs(_("The casefold feature may only be enabled when " + "the filesystem is unmounted.\n"), stderr); + return 1; + } + fs->super->s_encoding = EXT4_ENC_UTF8_12_1; + fs->super->s_encoding_flags = e2p_get_encoding_flags(EXT4_ENC_UTF8_12_1); + enabling_casefold = 1; + } + if (FEATURE_ON(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CSUM_SEED)) { if (!ext2fs_has_feature_metadata_csum(sb)) { @@ -2035,9 +2054,12 @@ void do_findfs(int argc, char **argv) static int parse_extended_opts(ext2_filsys fs, const char *opts) { + struct ext2_super_block *sb = fs->super; char *buf, *token, *next, *p, *arg; int len, hash_alg; int r_usage = 0; + int encoding = 0; + char *encoding_flags = NULL; len = strlen(opts); buf = malloc(len+1); @@ -2090,18 +2112,18 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts) "Setting multiple mount protection update " "interval to %lu seconds\n", intv), intv); - fs->super->s_mmp_update_interval = intv; + sb->s_mmp_update_interval = intv; ext2fs_mark_super_dirty(fs); } else if (!strcmp(token, "force_fsck")) { - fs->super->s_state |= EXT2_ERROR_FS; + sb->s_state |= EXT2_ERROR_FS; printf(_("Setting filesystem error flag to force fsck.\n")); ext2fs_mark_super_dirty(fs); } else if (!strcmp(token, "test_fs")) { - fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS; + sb->s_flags |= EXT2_FLAGS_TEST_FILESYS; printf("Setting test filesystem flag\n"); ext2fs_mark_super_dirty(fs); } else if (!strcmp(token, "^test_fs")) { - fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS; + sb->s_flags &= ~EXT2_FLAGS_TEST_FILESYS; printf("Clearing test filesystem flag\n"); ext2fs_mark_super_dirty(fs); } else if (strcmp(token, "stride") == 0) { @@ -2147,7 +2169,7 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts) r_usage++; continue; } - fs->super->s_def_hash_version = hash_alg; + sb->s_def_hash_version = hash_alg; printf(_("Setting default hash algorithm " "to %s (%d)\n"), arg, hash_alg); @@ -2163,9 +2185,68 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts) continue; } ext_mount_opts = strdup(arg); + } else if (!strcmp(token, "encoding")) { + if (!arg) { + r_usage++; + continue; + } + if (ext2fs_has_feature_encrypt(sb)) { + fprintf(stderr, _("error: Cannot enable casefolding if encryption is set\n")); + r_usage++; + continue; + } + if (mount_flags & EXT2_MF_MOUNTED) { + fputs(_("The casefold feature may only be enabled when " + "the filesystem is unmounted.\n"), stderr); + r_usage++; + continue; + } + if (ext2fs_has_feature_casefold(sb) && !enabling_casefold) { + fprintf(stderr, _("Cannot alter existing encoding\n")); + r_usage++; + continue; + } + encoding = e2p_str2encoding(arg); + if (encoding < 0) { + fprintf(stderr, _("Invalid encoding: %s\n"), arg); + r_usage++; + continue; + } + enabling_casefold = 1; + sb->s_encoding = encoding; + printf(_("Setting encoding to '%s'\n"), arg); + sb->s_encoding_flags = + e2p_get_encoding_flags(sb->s_encoding); + } else if (!strcmp(token, "encoding_flags")) { + if (!arg) { + r_usage++; + continue; + } + encoding_flags = arg; } else r_usage++; } + + if (encoding > 0 && !r_usage) { + sb->s_encoding_flags = + e2p_get_encoding_flags(sb->s_encoding); + + if (encoding_flags && + e2p_str2encoding_flags(sb->s_encoding, encoding_flags, + &sb->s_encoding_flags)) { + fprintf(stderr, _("error: Invalid encoding flag: %s\n"), + encoding_flags); + r_usage++; + } else if (encoding_flags) + printf(_("Setting encoding_flags to '%s'\n"), + encoding_flags); + ext2fs_set_feature_casefold(sb); + ext2fs_mark_super_dirty(fs); + } else if (encoding_flags && !r_usage) { + fprintf(stderr, _("error: An encoding must be explicitly " + "specified when passing encoding-flags\n")); + r_usage++; + } if (r_usage) { fprintf(stderr, "%s", _("\nBad options specified.\n\n" "Extended options are separated by commas, " @@ -2180,7 +2261,9 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts) "\tstripe_width=<RAID stride*data disks in blocks>\n" "\tforce_fsck\n" "\ttest_fs\n" - "\t^test_fs\n")); + "\t^test_fs\n" + "\tencoding=<encoding>\n" + "\tencoding_flags=<flags>\n")); free(buf); return 1; } |