[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180815194811.9423-22-krisman@collabora.co.uk>
Date: Wed, 15 Aug 2018 15:48:07 -0400
From: Gabriel Krisman Bertazi <krisman@...labora.co.uk>
To: tytso@....edu
Cc: linux-ext4@...r.kernel.org, kernel@...labora.com,
Gabriel Krisman Bertazi <krisman@...labora.co.uk>
Subject: [PATCH v2 21/25] ext4: Add encoding mount options
This patch implements two new mount options for ext4: encoding and
encoding_flags.
The encoding option receives a string that identifies the NLS encoding
to be used when mounting the filesystem. The user can optionally ask
for a specific version by appending the version string after a dash.
The encoding_flags argument allows the user to specify how the NLS
charset must behave. The exact behavior of the flags are defined at
ext4.h.
encoding_flags is ignored if the user didn't provide an encoding.
Signed-off-by: Gabriel Krisman Bertazi <krisman@...labora.co.uk>
---
fs/ext4/super.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 4ccb932a0dc7..1f1efde74523 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1390,6 +1390,7 @@ enum {
Opt_dioread_nolock, Opt_dioread_lock,
Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
Opt_max_dir_size_kb, Opt_nojournal_checksum, Opt_nombcache,
+ Opt_encoding, Opt_encoding_flags
};
static const match_table_t tokens = {
@@ -1474,6 +1475,8 @@ static const match_table_t tokens = {
{Opt_noinit_itable, "noinit_itable"},
{Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
{Opt_test_dummy_encryption, "test_dummy_encryption"},
+ {Opt_encoding, "encoding=%s"},
+ {Opt_encoding_flags, "encoding_flags=%u"},
{Opt_nombcache, "nombcache"},
{Opt_nombcache, "no_mbcache"}, /* for backward compatibility */
{Opt_removed, "check=none"}, /* mount option from ext2/3 */
@@ -1686,6 +1689,8 @@ static const struct mount_opts {
{Opt_max_dir_size_kb, 0, MOPT_GTE0},
{Opt_test_dummy_encryption, 0, MOPT_GTE0},
{Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET},
+ {Opt_encoding, 0, MOPT_EXT4_ONLY | MOPT_STRING},
+ {Opt_encoding_flags, 0, MOPT_EXT4_ONLY},
{Opt_err, 0, 0}
};
@@ -1712,6 +1717,27 @@ ext4_sb_read_encoding(const struct ext4_super_block *es,
return 0;
}
+
+static struct ext4_sb_encodings *ext4_parse_encoding_opt(char *arg)
+{
+ char *split;
+ struct ext4_sb_encodings *info;
+ ssize_t len = strlen(arg) + 1;
+
+ info = kzalloc(sizeof(struct ext4_sb_encodings) + len, GFP_KERNEL);
+ if (!info)
+ return NULL;
+
+ info->name = ((char*) &info[1]);
+ strncpy(info->name, arg, len);
+
+ split = strchr(info->name, '-');
+ if (split && *(split+1)) {
+ *split = '\0';
+ info->version = split+1;
+ }
+ return info;
+}
#endif
static int handle_mount_opt(struct super_block *sb, char *opt, int token,
@@ -1946,6 +1972,42 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
sbi->s_mount_opt |= m->mount_opt;
} else if (token == Opt_data_err_ignore) {
sbi->s_mount_opt &= ~m->mount_opt;
+ } else if (token == Opt_encoding) {
+ int ret = -1;
+#ifdef CONFIG_NLS
+ char *encoding = match_strdup(&args[0]);
+
+ if (!encoding)
+ return -ENOMEM;
+
+ if (ext4_has_feature_encrypt(sb)) {
+ ext4_msg(sb, KERN_ERR,
+ "Can't mount with both encoding and encryption");
+ goto encoding_out;
+ }
+
+ sbi->encoding_info = ext4_parse_encoding_opt(encoding);
+ if (!sbi->encoding_info) {
+ ext4_msg(sb, KERN_ERR,
+ "Encoding %s not supported by ext4", encoding);
+ goto encoding_out;
+ }
+
+ ret = 0;
+encoding_out:
+ kfree(encoding);
+#else
+ ext4_msg(sb, KERN_INFO, "encoding option not supported");
+#endif
+ return ret;
+ } else if (token == Opt_encoding_flags) {
+#ifdef CONFIG_NLS
+ sbi->encoding_flags = arg;
+ return 0;
+#else
+ ext4_msg(sb, KERN_INFO, "encoding flags option not supported");
+ return -1;
+#endif
} else {
if (!args->from)
arg = 1;
@@ -2032,6 +2094,35 @@ static int parse_options(char *options, struct super_block *sb,
return 0;
}
}
+
+#ifdef CONFIG_NLS
+ if (sbi->encoding_info) {
+ sbi->encoding = load_nls_version(sbi->encoding_info->name,
+ sbi->encoding_info->version,
+ sbi->encoding_flags);
+ if (IS_ERR(sbi->encoding)) {
+ ext4_msg(sb, KERN_ERR,
+ "Cannot load encoding: %s %s with flags 0x%hx",
+ sbi->encoding_info->name,
+ sbi->encoding_info->version?:"\b",
+ sbi->encoding_flags & EXT4_ENC_NLS_FL_MASK);
+
+ sbi->encoding = NULL;
+ sbi->encoding_flags = 0;
+ kfree(sbi->encoding_info);
+
+ return 0;
+ }
+ ext4_msg(sb, KERN_INFO,"Using encoding defined by mount option: "
+ "%s %s with flags 0x%hx", sbi->encoding_info->name,
+ sbi->encoding_info->version?:"\b", sbi->encoding_flags);
+ } else {
+ /* Make sure the flags are zeroed if the the user didn't
+ provide the encoding name. */
+ sbi->encoding_flags = 0;
+ }
+
+#endif
return 1;
}
--
2.18.0
Powered by blists - more mailing lists