Commit 49bd03cc authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Gabriel Krisman Bertazi
Browse files

unicode: pass a UNICODE_AGE() tripple to utf8_load



Don't bother with pointless string parsing when the caller can just pass
the version in the format that the core expects.  Also remove the
fallback to the latest version that none of the callers actually uses.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarGabriel Krisman Bertazi <krisman@collabora.com>
parent f3a9c823
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -2018,9 +2018,9 @@ static const struct mount_opts {
static const struct ext4_sb_encodings {
	__u16 magic;
	char *name;
	char *version;
	unsigned int version;
} ext4_sb_encoding_map[] = {
	{EXT4_ENC_UTF8_12_1, "utf8", "12.1.0"},
	{EXT4_ENC_UTF8_12_1, "utf8", UNICODE_AGE(12, 1, 0)},
};

static const struct ext4_sb_encodings *
@@ -4166,15 +4166,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
		encoding = utf8_load(encoding_info->version);
		if (IS_ERR(encoding)) {
			ext4_msg(sb, KERN_ERR,
				 "can't mount with superblock charset: %s-%s "
				 "can't mount with superblock charset: %s-%u.%u.%u "
				 "not supported by the kernel. flags: 0x%x.",
				 encoding_info->name, encoding_info->version,
				 encoding_info->name,
				 unicode_major(encoding_info->version),
				 unicode_minor(encoding_info->version),
				 unicode_rev(encoding_info->version),
				 encoding_flags);
			goto failed_mount;
		}
		ext4_msg(sb, KERN_INFO,"Using encoding defined by superblock: "
			 "%s-%s with flags 0x%hx", encoding_info->name,
			 encoding_info->version?:"\b", encoding_flags);
			 "%s-%u.%u.%u with flags 0x%hx", encoding_info->name,
			 unicode_major(encoding_info->version),
			 unicode_minor(encoding_info->version),
			 unicode_rev(encoding_info->version),
			 encoding_flags);

		sb->s_encoding = encoding;
		sb->s_encoding_flags = encoding_flags;
+12 −6
Original line number Diff line number Diff line
@@ -259,9 +259,9 @@ void f2fs_printk(struct f2fs_sb_info *sbi, const char *fmt, ...)
static const struct f2fs_sb_encodings {
	__u16 magic;
	char *name;
	char *version;
	unsigned int version;
} f2fs_sb_encoding_map[] = {
	{F2FS_ENC_UTF8_12_1, "utf8", "12.1.0"},
	{F2FS_ENC_UTF8_12_1, "utf8", UNICODE_AGE(12, 1, 0)},
};

static const struct f2fs_sb_encodings *
@@ -3847,15 +3847,21 @@ static int f2fs_setup_casefold(struct f2fs_sb_info *sbi)
		encoding = utf8_load(encoding_info->version);
		if (IS_ERR(encoding)) {
			f2fs_err(sbi,
				 "can't mount with superblock charset: %s-%s "
				 "can't mount with superblock charset: %s-%u.%u.%u "
				 "not supported by the kernel. flags: 0x%x.",
				 encoding_info->name, encoding_info->version,
				 encoding_info->name,
				 unicode_major(encoding_info->version),
				 unicode_minor(encoding_info->version),
				 unicode_rev(encoding_info->version),
				 encoding_flags);
			return PTR_ERR(encoding);
		}
		f2fs_info(sbi, "Using encoding defined by superblock: "
			 "%s-%s with flags 0x%hx", encoding_info->name,
			 encoding_info->version?:"\b", encoding_flags);
			 "%s-%u.%u.%u with flags 0x%hx", encoding_info->name,
			 unicode_major(encoding_info->version),
			 unicode_minor(encoding_info->version),
			 unicode_rev(encoding_info->version),
			 encoding_flags);

		sbi->sb->s_encoding = encoding;
		sbi->sb->s_encoding_flags = encoding_flags;
+5 −45
Original line number Diff line number Diff line
@@ -167,59 +167,19 @@ int utf8_normalize(const struct unicode_map *um, const struct qstr *str,
	}
	return -EINVAL;
}

EXPORT_SYMBOL(utf8_normalize);

static int utf8_parse_version(const char *version, unsigned int *maj,
			      unsigned int *min, unsigned int *rev)
{
	substring_t args[3];
	char version_string[12];
	static const struct match_token token[] = {
		{1, "%d.%d.%d"},
		{0, NULL}
	};

	strncpy(version_string, version, sizeof(version_string));

	if (match_token(version_string, token, args) != 1)
		return -EINVAL;

	if (match_int(&args[0], maj) || match_int(&args[1], min) ||
	    match_int(&args[2], rev))
		return -EINVAL;

	return 0;
}

struct unicode_map *utf8_load(const char *version)
struct unicode_map *utf8_load(unsigned int version)
{
	struct unicode_map *um = NULL;
	int unicode_version;

	if (version) {
		unsigned int maj, min, rev;
	struct unicode_map *um;

		if (utf8_parse_version(version, &maj, &min, &rev) < 0)
	if (!utf8version_is_supported(version))
		return ERR_PTR(-EINVAL);

		if (!utf8version_is_supported(maj, min, rev))
			return ERR_PTR(-EINVAL);

		unicode_version = UNICODE_AGE(maj, min, rev);
	} else {
		unicode_version = utf8version_latest();
		printk(KERN_WARNING"UTF-8 version not specified. "
		       "Assuming latest supported version (%d.%d.%d).",
		       (unicode_version >> 16) & 0xff,
		       (unicode_version >> 8) & 0xff,
		       (unicode_version & 0xff));
	}

	um = kzalloc(sizeof(struct unicode_map), GFP_KERNEL);
	if (!um)
		return ERR_PTR(-ENOMEM);
	um->version = unicode_version;
	um->version = version;
	return um;
}
EXPORT_SYMBOL(utf8_load);
+2 −9
Original line number Diff line number Diff line
@@ -15,13 +15,12 @@ struct utf8data {
#include "utf8data.h"
#undef __INCLUDED_FROM_UTF8NORM_C__

int utf8version_is_supported(u8 maj, u8 min, u8 rev)
int utf8version_is_supported(unsigned int version)
{
	int i = ARRAY_SIZE(utf8agetab) - 1;
	unsigned int sb_utf8version = UNICODE_AGE(maj, min, rev);

	while (i >= 0 && utf8agetab[i] != 0) {
		if (sb_utf8version == utf8agetab[i])
		if (version == utf8agetab[i])
			return 1;
		i--;
	}
@@ -29,12 +28,6 @@ int utf8version_is_supported(u8 maj, u8 min, u8 rev)
}
EXPORT_SYMBOL(utf8version_is_supported);

int utf8version_latest(void)
{
	return utf8vers;
}
EXPORT_SYMBOL(utf8version_latest);

/*
 * UTF-8 valid ranges.
 *
+8 −7
Original line number Diff line number Diff line
@@ -235,7 +235,7 @@ static void check_utf8_nfdicf(void)
static void check_utf8_comparisons(void)
{
	int i;
	struct unicode_map *table = utf8_load("12.1.0");
	struct unicode_map *table = utf8_load(UNICODE_AGE(12, 1, 0));

	if (IS_ERR(table)) {
		pr_err("%s: Unable to load utf8 %d.%d.%d. Skipping.\n",
@@ -269,18 +269,19 @@ static void check_utf8_comparisons(void)
static void check_supported_versions(void)
{
	/* Unicode 7.0.0 should be supported. */
	test(utf8version_is_supported(7, 0, 0));
	test(utf8version_is_supported(UNICODE_AGE(7, 0, 0)));

	/* Unicode 9.0.0 should be supported. */
	test(utf8version_is_supported(9, 0, 0));
	test(utf8version_is_supported(UNICODE_AGE(9, 0, 0)));

	/* Unicode 1x.0.0 (the latest version) should be supported. */
	test(utf8version_is_supported(latest_maj, latest_min, latest_rev));
	test(utf8version_is_supported(
		UNICODE_AGE(latest_maj, latest_min, latest_rev)));

	/* Next versions don't exist. */
	test(!utf8version_is_supported(13, 0, 0));
	test(!utf8version_is_supported(0, 0, 0));
	test(!utf8version_is_supported(-1, -1, -1));
	test(!utf8version_is_supported(UNICODE_AGE(13, 0, 0)));
	test(!utf8version_is_supported(UNICODE_AGE(0, 0, 0)));
	test(!utf8version_is_supported(UNICODE_AGE(-1, -1, -1)));
}

static int __init init_test_ucd(void)
Loading