bcachefs: Fix extent merging
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 25 Apr 2022 03:03:02 +0000 (23:03 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:32 +0000 (17:09 -0400)
When merging extents, we have to check that we won't overflow size
fields in any CRC entries - but the check for this was wrong, because in
the loop it was in we weren't keeping a pointer to the (packed, encoded)
CRC field.

Fix this by moving it to its own loop.

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

index c56925d94bfeb9f265cd86d995b616544001c3bc..d8f429ffe57cac7ca758c53a1620074900411f18 100644 (file)
@@ -307,8 +307,20 @@ bool bch2_extent_merge(struct bch_fs *c, struct bkey_s l, struct bkey_s_c r)
                            lp.crc.uncompressed_size +
                            rp.crc.uncompressed_size > (c->opts.encoded_extent_max >> 9))
                                return false;
+               }
+
+               en_l = extent_entry_next(en_l);
+               en_r = extent_entry_next(en_r);
+       }
+
+       en_l = l_ptrs.start;
+       en_r = r_ptrs.start;
+       while (en_l < l_ptrs.end && en_r < r_ptrs.end) {
+               if (extent_entry_is_crc(en_l)) {
+                       struct bch_extent_crc_unpacked crc_l = bch2_extent_crc_unpack(l.k, entry_to_crc(en_l));
+                       struct bch_extent_crc_unpacked crc_r = bch2_extent_crc_unpack(r.k, entry_to_crc(en_r));
 
-                       if (lp.crc.uncompressed_size + rp.crc.uncompressed_size >
+                       if (crc_l.uncompressed_size + crc_r.uncompressed_size >
                            bch2_crc_field_size_max[extent_entry_type(en_l)])
                                return false;
                }