]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
mke2fs: configure encoding during superblock initialization
authorGabriel Krisman Bertazi <krisman@collabora.co.uk>
Sat, 1 Dec 2018 00:39:03 +0000 (19:39 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 3 Dec 2018 04:31:22 +0000 (23:31 -0500)
This patch implements two new extended options to mkefs, allowing the
user to specify an encoding for file name operations and encoding flags
during filesystem creation.  We provide default flags for each encoding,
which the user can overwrite by passing -E fname_encoding-flags to mkfs.

If the user doesn't specify an encoding, the default value from
options.fname_encoding in mke2fs.conf.in file will be used.

Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/e2p/feature.c
lib/ext2fs/initialize.c
misc/mke2fs.8.in
misc/mke2fs.c
misc/mke2fs.conf.5.in
misc/mke2fs.conf.in

index 294a56a40b5267ddd402d8ac91026a52644c3698..ded87f5611dc86c2e3cd741942fd15058c1ffb6d 100644 (file)
@@ -110,7 +110,7 @@ static struct feature feature_list[] = {
        {       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_ENCRYPT,
                        "encrypt"},
        {       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FNAME_ENCODING,
-                       "encoding"},
+                       "fname_encoding"},
        {       0, 0, 0 },
 };
 
index 8c9e97fee831aabee3f7f4907ffa7877c219c005..30b1ae0333406a739fffd3e67c8d89550aebee85 100644 (file)
@@ -186,6 +186,10 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        set_field(s_flags, 0);
        assign_field(s_backup_bgs[0]);
        assign_field(s_backup_bgs[1]);
+
+       assign_field(s_encoding);
+       assign_field(s_encoding_flags);
+
        if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
                retval = EXT2_ET_UNSUPP_FEATURE;
                goto cleanup;
index 603e37e54a78b592866b6969f1be235d9ea045f7..4a2aa8fd96722a48899b3bfe281e65ed8604d3c2 100644 (file)
@@ -280,6 +280,31 @@ option is still accepted for backwards compatibility, but is deprecated.
 The following extended options are supported:
 .RS 1.2i
 .TP
+.BI fname_encoding= encoding-name
+Enable the
+.I fname_encoding
+feature in the super block and set
+.I encoding-name
+as the encoding to be used.  If
+.I encoding-name
+is not specified, the encoding defined in
+.BR mke2fs.conf (5)
+is used.
+.TP
+.BI fname_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.  To disable a
+flag, add it to the list with the prefix "no".
+
+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 mmp_update_interval= interval
 Adjust the initial MMP update interval to
 .I interval
index f05003fc30b96fd49eb26cae3620845777e8e795..41f2532bc84fbd583b2403dda45bfe2491a32d6a 100644 (file)
@@ -790,6 +790,8 @@ static void parse_extended_opts(struct ext2_super_block *param,
        int     len;
        int     r_usage = 0;
        int     ret;
+       int     encoding = -1;
+       char    *encoding_flags = NULL;
 
        len = strlen(opts);
        buf = malloc(len+1);
@@ -1056,6 +1058,31 @@ static void parse_extended_opts(struct ext2_super_block *param,
                        }
                } else if (!strcmp(token, "android_sparse")) {
                        android_sparse_file = 1;
+               } else if (!strcmp(token, "fname_encoding")) {
+                       if (!arg) {
+                               profile_get_string(profile, "options",
+                                                  "fname_encoding", 0, 0,
+                                                  &arg);
+                               if (!arg) {
+                                       r_usage++;
+                                       continue;
+                               }
+                       }
+
+                       encoding = e2p_str2encoding(arg);
+                       if (encoding < 0) {
+                               fprintf(stderr, _("Invalid encoding: %s"), arg);
+                               r_usage++;
+                               continue;
+                       }
+                       param->s_encoding = encoding;
+                       ext2fs_set_feature_fname_encoding(param);
+               } else if (!strcmp(token, "fname_encoding_flags")) {
+                       if (!arg) {
+                               r_usage++;
+                               continue;
+                       }
+                       encoding_flags = arg;
                } else {
                        r_usage++;
                        badopt = token;
@@ -1080,6 +1107,8 @@ static void parse_extended_opts(struct ext2_super_block *param,
                        "\ttest_fs\n"
                        "\tdiscard\n"
                        "\tnodiscard\n"
+                       "\tfname_encoding=<encoding>\n"
+                       "\tfname_encoding_flags=<flags>\n"
                        "\tquotatype=<quota type(s) to be enabled>\n\n"),
                        badopt ? badopt : "");
                free(buf);
@@ -1091,6 +1120,25 @@ static void parse_extended_opts(struct ext2_super_block *param,
                                  "multiple of stride %u.\n\n"),
                        param->s_raid_stripe_width, param->s_raid_stride);
 
+       if (ext2fs_has_feature_fname_encoding(param)) {
+               param->s_encoding_flags =
+                       e2p_get_encoding_flags(param->s_encoding);
+
+               if (encoding_flags &&
+                   e2p_str2encoding_flags(param->s_encoding, encoding_flags,
+                                          &param->s_encoding_flags)) {
+                       fprintf(stderr, _("error: Invalid encoding flag: %s\n"),
+                               encoding_flags);
+                       free(buf);
+                       exit(1);
+               }
+       } else if (encoding_flags) {
+               fprintf(stderr, _("error: An encoding must be explicitely "
+                                 "specified when passing encoding-flags\n"));
+               free(buf);
+               exit(1);
+       }
+
        free(buf);
 }
 
@@ -1112,6 +1160,7 @@ static __u32 ok_features[3] = {
                EXT4_FEATURE_INCOMPAT_64BIT|
                EXT4_FEATURE_INCOMPAT_INLINE_DATA|
                EXT4_FEATURE_INCOMPAT_ENCRYPT |
+               EXT4_FEATURE_INCOMPAT_FNAME_ENCODING |
                EXT4_FEATURE_INCOMPAT_CSUM_SEED |
                EXT4_FEATURE_INCOMPAT_LARGEDIR,
        /* R/O compat */
@@ -1518,6 +1567,8 @@ static void PRS(int argc, char *argv[])
        int             use_bsize;
        char            *newpath;
        int             pathlen = sizeof(PATH_SET) + 1;
+       char            *encoding_name = NULL;
+       int             encoding;
 
        if (oldpath)
                pathlen += strlen(oldpath);
@@ -2026,6 +2077,7 @@ profile_error:
                ext2fs_clear_feature_huge_file(&fs_param);
                ext2fs_clear_feature_metadata_csum(&fs_param);
                ext2fs_clear_feature_ea_inode(&fs_param);
+               ext2fs_clear_feature_fname_encoding(&fs_param);
        }
        edit_feature(fs_features ? fs_features : tmp,
                     &fs_param.s_feature_compat);
@@ -2341,6 +2393,26 @@ profile_error:
        if (packed_meta_blocks)
                journal_location = 0;
 
+       if (ext2fs_has_feature_fname_encoding(&fs_param)) {
+               profile_get_string(profile, "options", "fname_encoding",
+                                  0, 0, &encoding_name);
+               if (!encoding_name) {
+                       com_err(program_name, 0, "%s",
+                               _("Filename encoding type must be specified\n"
+                                 "Use -E fname_encoding=<name> instead"));
+                       exit(1);
+               }
+               encoding = e2p_str2encoding(encoding_name);
+               if (encoding < 0) {
+                       com_err(program_name, 0, "%s",
+                               _("Unknown default filename encoding\n"
+                                 "Use -E fname_encoding=<name> instead"));
+                       exit(1);
+               }
+               fs_param.s_encoding = encoding;
+               fs_param.s_encoding_flags = e2p_get_encoding_flags(encoding);
+       }
+
        /* Get options from profile */
        for (cpp = fs_types; *cpp; cpp++) {
                tmp = NULL;
@@ -2385,6 +2457,15 @@ profile_error:
                }
        }
 
+       if (ext2fs_has_feature_fname_encoding(&fs_param) &&
+           ext2fs_has_feature_encrypt(&fs_param)) {
+               com_err(program_name, 0, "%s",
+                       _("The encrypt and encoding features are not "
+                         "compatible.\nThey can not be both enabled "
+                         "simultaneously.\n"));
+                     exit (1);
+       }
+
        /* Don't allow user to set both metadata_csum and uninit_bg bits. */
        if (ext2fs_has_feature_metadata_csum(&fs_param) &&
            ext2fs_has_feature_gdt_csum(&fs_param))
index c086b4113b50a729069b3af8a4a90f29e0700272..ab93c7761a1601c11f24b697e7bc73a18ad991f0 100644 (file)
@@ -97,6 +97,10 @@ The following relations are defined in the
 .I [options]
 stanza.
 .TP
+.I fname_encoding
+This relation defines the file name encoding to be used by mke2fs, in
+case the user doesn't specify an encoding in the command line.
+.TP
 .I proceed_delay
 If this relation is set to a positive integer, then mke2fs will
 wait
index 01e35cf8315007b42a5c78475e776bfac58ad8f6..00afd9128a2774d1ab75f48acd2b6830292c73bf 100644 (file)
@@ -45,3 +45,6 @@
             blocksize = 4096
             inode_size = 128
        }
+
+[options]
+       fname_encoding = utf8