bcachefs: Fix for the bkey compat path
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 24 Apr 2020 18:08:18 +0000 (14:08 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:39 +0000 (17:08 -0400)
In the write path, we were calling bch2_bkey_ops.compat() in the wrong
place.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bkey_methods.c

index c97e1e9002cb6efa42e817d4da532644098ddcd7..55ef4032b37c159ee9b78fc2b2288a6a7338608a 100644 (file)
@@ -283,49 +283,64 @@ void __bch2_bkey_compat(unsigned level, enum btree_id btree_id,
        const struct bkey_ops *ops;
        struct bkey uk;
        struct bkey_s u;
-
-       if (big_endian != CPU_BIG_ENDIAN)
-               bch2_bkey_swab_key(f, k);
-
-       if (version < bcachefs_metadata_version_bkey_renumber)
-               bch2_bkey_renumber(__btree_node_type(level, btree_id), k, write);
-
-       if (version < bcachefs_metadata_version_inode_btree_change &&
-           btree_id == BTREE_ID_INODES) {
+       int i;
+
+       /*
+        * Do these operations in reverse order in the write path:
+        */
+
+       for (i = 0; i < 4; i++)
+       switch (!write ? i : 3 - i) {
+       case 0:
+               if (big_endian != CPU_BIG_ENDIAN)
+                       bch2_bkey_swab_key(f, k);
+               break;
+       case 1:
+               if (version < bcachefs_metadata_version_bkey_renumber)
+                       bch2_bkey_renumber(__btree_node_type(level, btree_id), k, write);
+               break;
+       case 2:
+               if (version < bcachefs_metadata_version_inode_btree_change &&
+                   btree_id == BTREE_ID_INODES) {
+                       if (!bkey_packed(k)) {
+                               struct bkey_i *u = packed_to_bkey(k);
+                               swap(u->k.p.inode, u->k.p.offset);
+                       } else if (f->bits_per_field[BKEY_FIELD_INODE] &&
+                                  f->bits_per_field[BKEY_FIELD_OFFSET]) {
+                               struct bkey_format tmp = *f, *in = f, *out = &tmp;
+
+                               swap(tmp.bits_per_field[BKEY_FIELD_INODE],
+                                    tmp.bits_per_field[BKEY_FIELD_OFFSET]);
+                               swap(tmp.field_offset[BKEY_FIELD_INODE],
+                                    tmp.field_offset[BKEY_FIELD_OFFSET]);
+
+                               if (!write)
+                                       swap(in, out);
+
+                               uk = __bch2_bkey_unpack_key(in, k);
+                               swap(uk.p.inode, uk.p.offset);
+                               BUG_ON(!bch2_bkey_pack_key(k, &uk, out));
+                       }
+               }
+               break;
+       case 3:
                if (!bkey_packed(k)) {
-                       struct bkey_i *u = packed_to_bkey(k);
-                       swap(u->k.p.inode, u->k.p.offset);
-               } else if (f->bits_per_field[BKEY_FIELD_INODE] &&
-                          f->bits_per_field[BKEY_FIELD_OFFSET]) {
-                       struct bkey_format tmp = *f, *in = f, *out = &tmp;
-
-                       swap(tmp.bits_per_field[BKEY_FIELD_INODE],
-                            tmp.bits_per_field[BKEY_FIELD_OFFSET]);
-                       swap(tmp.field_offset[BKEY_FIELD_INODE],
-                            tmp.field_offset[BKEY_FIELD_OFFSET]);
-
-                       if (!write)
-                               swap(in, out);
-
-                       uk = __bch2_bkey_unpack_key(in, k);
-                       swap(uk.p.inode, uk.p.offset);
-                       BUG_ON(!bch2_bkey_pack_key(k, &uk, out));
+                       u = bkey_i_to_s(packed_to_bkey(k));
+               } else {
+                       uk = __bch2_bkey_unpack_key(f, k);
+                       u.k = &uk;
+                       u.v = bkeyp_val(f, k);
                }
-       }
 
-       if (!bkey_packed(k)) {
-               u = bkey_i_to_s(packed_to_bkey(k));
-       } else {
-               uk = __bch2_bkey_unpack_key(f, k);
-               u.k = &uk;
-               u.v = bkeyp_val(f, k);
-       }
+               if (big_endian != CPU_BIG_ENDIAN)
+                       bch2_bkey_swab_val(u);
 
-       if (big_endian != CPU_BIG_ENDIAN)
-               bch2_bkey_swab_val(u);
+               ops = &bch2_bkey_ops[k->type];
 
-       ops = &bch2_bkey_ops[k->type];
-
-       if (ops->compat)
-               ops->compat(btree_id, version, big_endian, write, u);
+               if (ops->compat)
+                       ops->compat(btree_id, version, big_endian, write, u);
+               break;
+       default:
+               BUG();
+       }
 }