diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-08-21 18:35:15 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:25 -0400 |
commit | e42951b0aa50bb67b29da1af1099013c1aeb1d9d (patch) | |
tree | d423c9d3eb2c00af621f1ffa42939259f4ce0f49 /fs | |
parent | 76426098e419c1732efc3f88166f3f3592c215c9 (diff) |
bcachefs: Fix bch2_sort_repack_merge()
bch2_bkey_normalize() modifies the value, and we were modifying the
original value in the src btree node - but, we're called without a write
lock held on the src node. Oops...
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/bkey_sort.c | 19 | ||||
-rw-r--r-- | fs/bcachefs/extents.c | 4 |
2 files changed, 10 insertions, 13 deletions
diff --git a/fs/bcachefs/bkey_sort.c b/fs/bcachefs/bkey_sort.c index 9f5d9b4bf1c9..e32fad5a91ac 100644 --- a/fs/bcachefs/bkey_sort.c +++ b/fs/bcachefs/bkey_sort.c @@ -415,25 +415,22 @@ bch2_sort_repack_merge(struct bch_fs *c, struct bkey_format *out_f, bool filter_whiteouts) { - struct bkey_packed *prev = NULL, *k_packed, *next; - struct bkey k_unpacked; + struct bkey_packed *prev = NULL, *k_packed; struct bkey_s k; struct btree_nr_keys nr; + BKEY_PADDED(k) tmp; memset(&nr, 0, sizeof(nr)); - next = bch2_btree_node_iter_next_all(iter, src); - while ((k_packed = next)) { - /* - * The filter might modify the size of @k's value, so advance - * the iterator first: - */ - next = bch2_btree_node_iter_next_all(iter, src); - + while ((k_packed = bch2_btree_node_iter_next_all(iter, src))) { if (filter_whiteouts && bkey_whiteout(k_packed)) continue; - k = __bkey_disassemble(src, k_packed, &k_unpacked); + EBUG_ON(bkeyp_val_u64s(&src->format, k_packed) > + BKEY_EXTENT_VAL_U64s_MAX); + + bch2_bkey_unpack(src, &tmp.k, k_packed); + k = bkey_i_to_s(&tmp.k); if (filter_whiteouts && bch2_bkey_normalize(c, k)) diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 81ec55526ce9..779ee42350ad 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -1590,9 +1590,9 @@ bool bch2_extent_normalize(struct bch_fs *c, struct bkey_s k) /* will only happen if all pointers were cached: */ if (!bkey_val_u64s(k.k)) - k.k->type = KEY_TYPE_deleted; + k.k->type = KEY_TYPE_discard; - return false; + return bkey_whiteout(k.k); } void bch2_bkey_mark_replicas_cached(struct bch_fs *c, struct bkey_s k, |