mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
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: Daniel 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
This commit is contained in:
@@ -669,52 +669,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 };
|
||||
const struct dentry *parent = READ_ONCE(dentry->d_parent);
|
||||
const struct inode *inode = READ_ONCE(parent->d_inode);
|
||||
|
||||
if (!inode || !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;
|
||||
const struct inode *inode = READ_ONCE(dentry->d_inode);
|
||||
unsigned char *norm;
|
||||
int len, ret = 0;
|
||||
|
||||
if (!inode || !IS_CASEFOLDED(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
|
||||
|
||||
@@ -1373,14 +1373,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
|
||||
*/
|
||||
@@ -1430,10 +1422,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;
|
||||
|
||||
@@ -275,7 +275,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 };
|
||||
|
||||
@@ -1286,8 +1286,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)
|
||||
@@ -1299,7 +1299,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)
|
||||
@@ -1316,7 +1316,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;
|
||||
}
|
||||
@@ -1325,7 +1325,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) {
|
||||
@@ -1362,7 +1362,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};
|
||||
@@ -2170,9 +2170,6 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
||||
struct buffer_head *bh = NULL;
|
||||
struct ext4_dir_entry_2 *de;
|
||||
struct super_block *sb;
|
||||
#ifdef CONFIG_UNICODE
|
||||
struct ext4_sb_info *sbi;
|
||||
#endif
|
||||
struct ext4_filename fname;
|
||||
int retval;
|
||||
int dx_fallback=0;
|
||||
@@ -2189,9 +2186,8 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
sbi = EXT4_SB(sb);
|
||||
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
|
||||
|
||||
|
||||
@@ -1102,7 +1102,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);
|
||||
}
|
||||
@@ -3913,7 +3913,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;
|
||||
@@ -3944,8 +3944,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
|
||||
|
||||
@@ -4552,7 +4552,7 @@ no_journal:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
if (sbi->s_encoding)
|
||||
if (sb->s_encoding)
|
||||
sb->s_d_op = &ext4_dentry_ops;
|
||||
#endif
|
||||
|
||||
@@ -4738,7 +4738,7 @@ failed_mount:
|
||||
crypto_free_shash(sbi->s_chksum_driver);
|
||||
|
||||
#ifdef CONFIG_UNICODE
|
||||
utf8_unload(sbi->s_encoding);
|
||||
utf8_unload(sb->s_encoding);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_QUOTA
|
||||
|
||||
Reference in New Issue
Block a user