bcachefs: Fix bch2_sort_keys() to not modify src keys
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 16 Jan 2020 03:53:49 +0000 (22:53 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:34 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bkey_sort.c
fs/bcachefs/bset.h
fs/bcachefs/btree_iter.c

index 18f842012f05ab1afe57a630c5c2c898c281669a..1c8e5a80e32a215321d70bfe446c70e0e90c8635 100644 (file)
@@ -254,23 +254,18 @@ unsigned bch2_sort_keys(struct bkey_packed *dst,
        sort_iter_sort(iter, sort_keys_cmp);
 
        while ((in = sort_iter_next(iter, sort_keys_cmp))) {
+               bool needs_whiteout = false;
+
                if (bkey_whiteout(in) &&
                    (filter_whiteouts || !in->needs_whiteout))
                        continue;
 
-               if (bkey_whiteout(in) &&
-                   (next = sort_iter_peek(iter)) &&
-                   !bkey_cmp_packed(iter->b, in, next)) {
+               while ((next = sort_iter_peek(iter)) &&
+                      !bkey_cmp_packed(iter->b, in, next)) {
                        BUG_ON(in->needs_whiteout &&
                               next->needs_whiteout);
-                       /*
-                        * XXX racy, called with read lock from write path
-                        *
-                        * leads to spurious BUG_ON() in bkey_unpack_key() in
-                        * debug mode
-                        */
-                       next->needs_whiteout |= in->needs_whiteout;
-                       continue;
+                       needs_whiteout |= in->needs_whiteout;
+                       in = sort_iter_next(iter, sort_keys_cmp);
                }
 
                if (bkey_whiteout(in)) {
@@ -279,6 +274,7 @@ unsigned bch2_sort_keys(struct bkey_packed *dst,
                } else {
                        bkey_copy(out, in);
                }
+               out->needs_whiteout |= needs_whiteout;
                out = bkey_next(out);
        }
 
index 5c3c5fbea4b7a3cf85b701534b97fcba55440dbb..50d0ce7d1afab0dfaed7fd70ae4b3522da9afcd3 100644 (file)
@@ -199,12 +199,6 @@ __bkey_unpack_key_format_checked(const struct btree *b,
                if (btree_keys_expensive_checks(b)) {
                        struct bkey dst2 = __bch2_bkey_unpack_key(&b->format, src);
 
-                       /*
-                        * hack around a harmless race when compacting whiteouts
-                        * for a write:
-                        */
-                       dst2.needs_whiteout = dst->needs_whiteout;
-
                        BUG_ON(memcmp(dst, &dst2, sizeof(*dst)));
                }
        }
index d1e83cfba47f1c1006ff1098ecd975d00ec68f09..5e220284b0b34249fec2759362c6420d9154fd7c 100644 (file)
@@ -1339,12 +1339,6 @@ static inline struct bkey_s_c btree_iter_peek_uptodate(struct btree_iter *iter)
                if (debug_check_iterators(iter->trans->c)) {
                        struct bkey k = bkey_unpack_key(l->b, _k);
 
-                       /*
-                        * this flag is internal to the btree code,
-                        * we don't care if it doesn't match - if it's now set
-                        * it just means the key has been written out to disk:
-                        */
-                       k.needs_whiteout = iter->k.needs_whiteout;
                        BUG_ON(memcmp(&k, &iter->k, sizeof(k)));
                }