On Tue, Jul 07, 2020 at 04:31:22AM -0700, Daniel Rosenberg wrote: > This switches f2fs over to the generic support provided in > the previous patch. > > 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 <drosen@xxxxxxxxxx> > --- > fs/f2fs/dir.c | 83 +++++------------------------------------ > fs/f2fs/f2fs.h | 4 -- > fs/f2fs/super.c | 10 ++--- > fs/f2fs/sysfs.c | 10 +++-- > include/linux/f2fs_fs.h | 3 -- > 5 files changed, 20 insertions(+), 90 deletions(-) Looks good, you can add: Reviewed-by: Eric Biggers <ebiggers@xxxxxxxxxx> One nit below: > #ifdef CONFIG_UNICODE > -static int f2fs_d_compare(const struct dentry *dentry, unsigned int len, > - const char *str, const struct qstr *name) > -{ > - const struct dentry *parent = READ_ONCE(dentry->d_parent); > - const struct inode *dir = READ_ONCE(parent->d_inode); > - const struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); > - struct qstr entry = QSTR_INIT(str, len); > - char strbuf[DNAME_INLINE_LEN]; > - int res; > - > - if (!dir || !IS_CASEFOLDED(dir)) > - goto fallback; > - > - /* > - * 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; > - entry.name = strbuf; > - /* prevent compiler from optimizing out the temporary buffer */ > - barrier(); > - } > - > - res = utf8_strncasecmp(sbi->s_encoding, name, &entry); > - if (res >= 0) > - return res; > - > - if (f2fs_has_strict_mode(sbi)) > - return -EINVAL; > -fallback: > - if (len != name->len) > - return 1; > - return !!memcmp(str, name->name, len); > -} > - > -static int f2fs_d_hash(const struct dentry *dentry, struct qstr *str) > -{ > - struct f2fs_sb_info *sbi = F2FS_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)) > - return 0; > - > - norm = f2fs_kmalloc(sbi, PATH_MAX, GFP_ATOMIC); > - if (!norm) > - return -ENOMEM; > - > - len = utf8_casefold(um, str, norm, PATH_MAX); > - if (len < 0) { > - if (f2fs_has_strict_mode(sbi)) > - ret = -EINVAL; > - goto out; > - } > - str->hash = full_name_hash(dentry, norm, len); > -out: > - kvfree(norm); > - return ret; > -} > > const struct dentry_operations f2fs_dentry_ops = { > - .d_hash = f2fs_d_hash, > - .d_compare = f2fs_d_compare, > + .d_hash = generic_ci_d_hash, > + .d_compare = generic_ci_d_compare, > }; > #endif This leaves an extra blank line just above f2fs_dentry_ops. - Eric