]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Fix casefold lookups
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 24 Apr 2025 16:58:06 +0000 (12:58 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 24 Apr 2025 23:09:52 +0000 (19:09 -0400)
Add casefolding to bch2_lookup_trans:

During the delay between when casefolding was written and when it was
merged, the main filesystem lookup path grew self healing - which meant
it was no longer using bch2_dirent_lookup_trans(), where casefolding on
lookups happens.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/dirent.c
fs/bcachefs/dirent.h
fs/bcachefs/fs.c

index 8488a7578115140b4c7c39760d29001b260c6477..92ee59d9e00eced56f4ff53b57579c97c5c91873 100644 (file)
@@ -13,8 +13,8 @@
 
 #include <linux/dcache.h>
 
-static int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
-                               const struct qstr *str, struct qstr *out_cf)
+int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
+                 const struct qstr *str, struct qstr *out_cf)
 {
        *out_cf = (struct qstr) QSTR_INIT(NULL, 0);
 
@@ -35,18 +35,6 @@ static int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *
 #endif
 }
 
-static inline int bch2_maybe_casefold(struct btree_trans *trans,
-                                     const struct bch_hash_info *info,
-                                     const struct qstr *str, struct qstr *out_cf)
-{
-       if (likely(!info->cf_encoding)) {
-               *out_cf = *str;
-               return 0;
-       } else {
-               return bch2_casefold(trans, info, str, out_cf);
-       }
-}
-
 static unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d)
 {
        if (bkey_val_bytes(d.k) < offsetof(struct bch_dirent, d_name))
index 0880772b80a9b1150619a4ff81a53d2937ed6e5b..9838a7ba7ed1b5679b968666edcf09684beebc79 100644 (file)
@@ -23,6 +23,21 @@ struct bch_fs;
 struct bch_hash_info;
 struct bch_inode_info;
 
+int bch2_casefold(struct btree_trans *, const struct bch_hash_info *,
+                 const struct qstr *, struct qstr *);
+
+static inline int bch2_maybe_casefold(struct btree_trans *trans,
+                                     const struct bch_hash_info *info,
+                                     const struct qstr *str, struct qstr *out_cf)
+{
+       if (likely(!info->cf_encoding)) {
+               *out_cf = *str;
+               return 0;
+       } else {
+               return bch2_casefold(trans, info, str, out_cf);
+       }
+}
+
 struct qstr bch2_dirent_get_name(struct bkey_s_c_dirent d);
 
 static inline unsigned dirent_val_u64s(unsigned len, unsigned cf_len)
index 7c1943c83bf6e95ce1411efc045fdfe2fee507ce..c73e970528163439869066b057e43d787b218e3a 100644 (file)
@@ -648,13 +648,18 @@ static struct bch_inode_info *bch2_lookup_trans(struct btree_trans *trans,
                        const struct qstr *name)
 {
        struct bch_fs *c = trans->c;
-       struct btree_iter dirent_iter = {};
        subvol_inum inum = {};
        struct printbuf buf = PRINTBUF;
 
+       struct qstr lookup_name;
+       int ret = bch2_maybe_casefold(trans, dir_hash_info, name, &lookup_name);
+       if (ret)
+               return ERR_PTR(ret);
+
+       struct btree_iter dirent_iter = {};
        struct bkey_s_c k = bch2_hash_lookup(trans, &dirent_iter, bch2_dirent_hash_desc,
-                                            dir_hash_info, dir, name, 0);
-       int ret = bkey_err(k);
+                                            dir_hash_info, dir, &lookup_name, 0);
+       ret = bkey_err(k);
        if (ret)
                return ERR_PTR(ret);