Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2cb7739 authored by Daniel Rosenberg's avatar Daniel Rosenberg
Browse files

FROMLIST: ext4: Use generic casefolding support



This switches ext4 over to the generic support provided in
commit 65832afbeaaf ("fs: Add standard casefolding support")

Signed-off-by: default avatarDaniel Rosenberg <drosen@google.com>
Test: Boots, /data/media is case insensitive
Bug: 138322712
Link: https://lore.kernel.org/linux-f2fs-devel/20200208013552.241832-1-drosen@google.com/T/#t
Change-Id: I3a0705278100590df4c7cdd0dcdf945e9f11feb7
parent ed5f8d20
Loading
Loading
Loading
Loading
+2 −43
Original line number Diff line number Diff line
@@ -664,49 +664,8 @@ const struct file_operations ext4_dir_operations = {
};

#ifdef CONFIG_UNICODE
static int ext4_d_compare(const struct dentry *dentry, unsigned int len,
			  const char *str, const struct qstr *name)
{
	struct qstr qstr = {.name = str, .len = len };
	struct inode *inode = dentry->d_parent->d_inode;

	if (!IS_CASEFOLDED(inode) || !EXT4_SB(inode->i_sb)->s_encoding) {
		if (len != name->len)
			return -1;
		return memcmp(str, name->name, len);
	}

	return ext4_ci_compare(inode, name, &qstr, false);
}

static int ext4_d_hash(const struct dentry *dentry, struct qstr *str)
{
	const struct ext4_sb_info *sbi = EXT4_SB(dentry->d_sb);
	const struct unicode_map *um = sbi->s_encoding;
	unsigned char *norm;
	int len, ret = 0;

	if (!IS_CASEFOLDED(dentry->d_inode) || !um)
		return 0;

	norm = kmalloc(PATH_MAX, GFP_ATOMIC);
	if (!norm)
		return -ENOMEM;

	len = utf8_casefold(um, str, norm, PATH_MAX);
	if (len < 0) {
		if (ext4_has_strict_mode(sbi))
			ret = -EINVAL;
		goto out;
	}
	str->hash = full_name_hash(dentry, norm, len);
out:
	kfree(norm);
	return ret;
}

const struct dentry_operations ext4_dentry_ops = {
	.d_hash = ext4_d_hash,
	.d_compare = ext4_d_compare,
	.d_hash = generic_ci_d_hash,
	.d_compare = generic_ci_d_compare,
};
#endif
+0 −12
Original line number Diff line number Diff line
@@ -1376,14 +1376,6 @@ struct ext4_super_block {

#define EXT4_ENC_UTF8_12_1	1

/*
 * Flags for ext4_sb_info.s_encoding_flags.
 */
#define EXT4_ENC_STRICT_MODE_FL	(1 << 0)

#define ext4_has_strict_mode(sbi) \
	(sbi->s_encoding_flags & EXT4_ENC_STRICT_MODE_FL)

/*
 * fourth extended-fs super-block data in memory
 */
@@ -1435,10 +1427,6 @@ struct ext4_sb_info {
	struct kobject s_kobj;
	struct completion s_kobj_unregister;
	struct super_block *s_sb;
#ifdef CONFIG_UNICODE
	struct unicode_map *s_encoding;
	__u16 s_encoding_flags;
#endif

	/* Journaling */
	struct journal_s *s_journal;
+1 −1
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
		   struct dx_hash_info *hinfo)
{
#ifdef CONFIG_UNICODE
	const struct unicode_map *um = EXT4_SB(dir->i_sb)->s_encoding;
	const struct unicode_map *um = dir->i_sb->s_encoding;
	int r, dlen;
	unsigned char *buff;
	struct qstr qstr = {.name = name, .len = len };
+8 −10
Original line number Diff line number Diff line
@@ -1280,8 +1280,8 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
		    const struct qstr *entry, bool quick)
{
	const struct ext4_sb_info *sbi = EXT4_SB(parent->i_sb);
	const struct unicode_map *um = sbi->s_encoding;
	const struct super_block *sb = parent->i_sb;
	const struct unicode_map *um = sb->s_encoding;
	int ret;

	if (quick)
@@ -1293,7 +1293,7 @@ int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
		/* Handle invalid character sequence as either an error
		 * or as an opaque byte sequence.
		 */
		if (ext4_has_strict_mode(sbi))
		if (sb_has_enc_strict_mode(sb))
			return -EINVAL;

		if (name->len != entry->len)
@@ -1310,7 +1310,7 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
{
	int len;

	if (!IS_CASEFOLDED(dir) || !EXT4_SB(dir->i_sb)->s_encoding) {
	if (!needs_casefold(dir)) {
		cf_name->name = NULL;
		return;
	}
@@ -1319,7 +1319,7 @@ void ext4_fname_setup_ci_filename(struct inode *dir, const struct qstr *iname,
	if (!cf_name->name)
		return;

	len = utf8_casefold(EXT4_SB(dir->i_sb)->s_encoding,
	len = utf8_casefold(dir->i_sb->s_encoding,
			    iname, cf_name->name,
			    EXT4_NAME_LEN);
	if (len <= 0) {
@@ -1356,7 +1356,7 @@ static inline bool ext4_match(const struct inode *parent,
#endif

#ifdef CONFIG_UNICODE
	if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent)) {
	if (needs_casefold(parent)) {
		if (fname->cf_name.name) {
			struct qstr cf = {.name = fname->cf_name.name,
					  .len = fname->cf_name.len};
@@ -2172,7 +2172,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
	struct ext4_dir_entry_2 *de;
	struct ext4_dir_entry_tail *t;
	struct super_block *sb;
	struct ext4_sb_info *sbi;
	struct ext4_filename fname;
	int	retval;
	int	dx_fallback=0;
@@ -2184,14 +2183,13 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
		csum_size = sizeof(struct ext4_dir_entry_tail);

	sb = dir->i_sb;
	sbi = EXT4_SB(sb);
	blocksize = sb->s_blocksize;
	if (!dentry->d_name.len)
		return -EINVAL;

#ifdef CONFIG_UNICODE
	if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) &&
	    sbi->s_encoding && utf8_validate(sbi->s_encoding, &dentry->d_name))
	if (sb_has_enc_strict_mode(sb) && IS_CASEFOLDED(dir) &&
	    sb->s_encoding && utf8_validate(sb->s_encoding, &dentry->d_name))
		return -EINVAL;
#endif

+6 −6
Original line number Diff line number Diff line
@@ -989,7 +989,7 @@ static void ext4_put_super(struct super_block *sb)
	kfree(sbi->s_blockgroup_lock);
	fs_put_dax(sbi->s_daxdev);
#ifdef CONFIG_UNICODE
	utf8_unload(sbi->s_encoding);
	utf8_unload(sb->s_encoding);
#endif
	kfree(sbi);
}
@@ -3815,7 +3815,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
		goto failed_mount;

#ifdef CONFIG_UNICODE
	if (ext4_has_feature_casefold(sb) && !sbi->s_encoding) {
	if (ext4_has_feature_casefold(sb) && !sb->s_encoding) {
		const struct ext4_sb_encodings *encoding_info;
		struct unicode_map *encoding;
		__u16 encoding_flags;
@@ -3846,8 +3846,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
			 "%s-%s with flags 0x%hx", encoding_info->name,
			 encoding_info->version?:"\b", encoding_flags);

		sbi->s_encoding = encoding;
		sbi->s_encoding_flags = encoding_flags;
		sb->s_encoding = encoding;
		sb->s_encoding_flags = encoding_flags;
	}
#endif

@@ -4470,7 +4470,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
	}

#ifdef CONFIG_UNICODE
	if (sbi->s_encoding)
	if (sb->s_encoding)
		sb->s_d_op = &ext4_dentry_ops;
#endif

@@ -4654,7 +4654,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
		crypto_free_shash(sbi->s_chksum_driver);

#ifdef CONFIG_UNICODE
	utf8_unload(sbi->s_encoding);
	utf8_unload(sb->s_encoding);
#endif

#ifdef CONFIG_QUOTA