Commit 24d314d4 authored by Gabriel Krisman Bertazi's avatar Gabriel Krisman Bertazi
Browse files

ext4: Include encoding information on the superblock


Signed-off-by: default avatarGabriel Krisman Bertazi <krisman@collabora.co.uk>
parent de54f8db
......@@ -1372,6 +1372,8 @@ struct ext4_sb_info {
struct kobject s_kobj;
struct completion s_kobj_unregister;
struct super_block *s_sb;
unsigned encoding;
unsigned encoding_version;
/* Journaling */
struct journal_s *s_journal;
......
......@@ -40,6 +40,7 @@
#include <linux/dax.h>
#include <linux/cleancache.h>
#include <linux/uaccess.h>
#include <linux/fsucd.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
......@@ -1351,7 +1352,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_ignore_case,
Opt_ignore_case, Opt_encoding,
};
static const match_table_t tokens = {
......@@ -1435,6 +1436,7 @@ static const match_table_t tokens = {
{Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
{Opt_test_dummy_encryption, "test_dummy_encryption"},
{Opt_ignore_case, "ignorecase"},
{Opt_encoding, "encoding=%s"},
{Opt_nombcache, "nombcache"},
{Opt_nombcache, "no_mbcache"}, /* for backward compatibility */
{Opt_removed, "check=none"}, /* mount option from ext2/3 */
......@@ -1537,6 +1539,47 @@ static int clear_qf_name(struct super_block *sb, int qtype)
}
#endif
enum {Enc_ascii, Enc_utf8, Enc_unsupported};
static const match_table_t encoding_tokens = {
{Enc_ascii, "ascii"},
{Enc_utf8, "utf8-%d.%d.%d"},
{Enc_unsupported, NULL}
};
#define ENCODING_ASCII 0x01
#define ENCODING_UTF8 0x02
static unsigned int encoding_magic_number(char *p, int *encoding,
unsigned int *version)
{
substring_t args[MAX_OPT_ARGS];
int token = match_token(p, encoding_tokens, args);
if (token == Enc_unsupported) {
return -1;
} else if (token == Enc_ascii) {
*encoding = ENCODING_ASCII;
*version = 0;
} else if (token == Enc_utf8) {
int maj, min, rev;
if (match_int(&args[0], &maj) ||
match_int(&args[1], &min) ||
match_int(&args[2], &rev))
return -1;
if (fsucd_get_magic_number(maj, min, rev, version))
return -1;
*encoding = ENCODING_UTF8;
} else {
/* Should be dead. */
return -1;
}
return 0;
}
#define MOPT_SET 0x0001
#define MOPT_CLEAR 0x0002
#define MOPT_NOSUPPORT 0x0004
......@@ -1645,6 +1688,7 @@ 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_err, 0, 0}
};
......@@ -1883,6 +1927,21 @@ 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 encoding, version;
char *str = match_strdup(&args[0]);
int err = encoding_magic_number(str, &encoding, &version);
if (err) {
ext4_msg(sb, KERN_ERR, "Encoding %s not supported\n",
str);
return -1;
}
sbi->encoding = encoding;
sbi->encoding_version = version;
kfree(str);
} else {
if (!args->from)
arg = 1;
......@@ -1969,6 +2028,12 @@ static int parse_options(char *options, struct super_block *sb,
return 0;
}
}
if (test_opt2(sb, CASE_INSENSITIVE) && !sbi->encoding) {
ext4_msg(sb, KERN_WARNING, "Encoding not explicitly specified "
"or identified on the superblock. ASCII is assumed.");
}
return 1;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment