From f8f4acb6cded4e455b2d390ce2221391fc3f09ee Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Wed, 28 Oct 2020 05:08:20 +0000 Subject: ext4: use generic casefolding support This switches ext4 over to the generic support provided in libfs. Since casefolded dentries behave the same in ext4 and f2fs, we decrease the maintenance burden by unifying them, and any optimizations will immediately apply to both. Signed-off-by: Daniel Rosenberg Reviewed-by: Eric Biggers Link: https://lore.kernel.org/r/20201028050820.1636571-1-drosen@google.com Signed-off-by: Theodore Ts'o --- fs/ext4/dir.c | 64 ++--------------------------------------------------------- 1 file changed, 2 insertions(+), 62 deletions(-) (limited to 'fs/ext4/dir.c') diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 5b81f3b080ee..ca50c90adc4c 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -669,68 +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 = d_inode_rcu(parent); - char strbuf[DNAME_INLINE_LEN]; - - if (!inode || !IS_CASEFOLDED(inode) || - !EXT4_SB(inode->i_sb)->s_encoding) { - if (len != name->len) - return -1; - return memcmp(str, name->name, len); - } - - /* - * If the dentry name is stored in-line, then it may be concurrently - * modified by a rename. If this happens, the VFS will eventually retry - * the lookup, so it doesn't matter what ->d_compare() returns. - * However, it's unsafe to call utf8_strncasecmp() with an unstable - * string. Therefore, we have to copy the name into a temporary buffer. - */ - if (len <= DNAME_INLINE_LEN - 1) { - memcpy(strbuf, str, len); - strbuf[len] = 0; - qstr.name = strbuf; - /* prevent compiler from optimizing out the temporary buffer */ - barrier(); - } - - 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 = d_inode_rcu(dentry); - 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 -- cgit v1.2.3