diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-09 00:13:11 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-09 15:37:04 -0400 |
commit | 590048456e4061eb80c4a69f48a123ff0f10dbbb (patch) | |
tree | b3a62e9fe1437dcc37849b9067c793fea1217cb6 | |
parent | a70496b1c523ec064b861e4b1b2612e4a1d4d4b8 (diff) |
bcachefs: backpointer_matches_key()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/backpointers.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c index 7fa37c768b74..7f8ef554d8cd 100644 --- a/fs/bcachefs/backpointers.c +++ b/fs/bcachefs/backpointers.c @@ -424,6 +424,32 @@ out: return ret; } +static bool backpointer_matches_key(struct bch_fs *c, + struct bpos alloc_pos, + struct bch_backpointer bp, + struct bkey_s_c k) +{ + struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); + const union bch_extent_entry *entry; + struct extent_ptr_decoded p; + + bkey_for_each_ptr_decode(k.k, ptrs, p, entry) { + struct bpos alloc_pos2; + struct bch_backpointer bp2; + + if (p.ptr.cached) + continue; + + bch2_pointer_to_bucket_and_backpointer(c, bp.btree_id, bp.level, + k, p, &alloc_pos2, &bp2); + if (!bpos_cmp(alloc_pos, alloc_pos2) && + !memcmp(&bp, &bp2, sizeof(bp))) + return true; + } + + return false; +} + static void backpointer_not_found(struct btree_trans *trans, struct bpos alloc_pos, u64 bp_offset, @@ -467,9 +493,6 @@ struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans, struct bch_backpointer bp) { struct bch_fs *c = trans->c; - struct bkey_ptrs_c ptrs; - const union bch_extent_entry *entry; - struct extent_ptr_decoded p; struct bkey_s_c k; bch2_trans_node_iter_init(trans, iter, @@ -487,18 +510,8 @@ struct bkey_s_c bch2_backpointer_get_key(struct btree_trans *trans, if (bp.level == c->btree_roots[bp.btree_id].level + 1) k = bkey_i_to_s_c(&c->btree_roots[bp.btree_id].key); - /* Check if key matches backpointer: */ - ptrs = bch2_bkey_ptrs_c(k); - bkey_for_each_ptr_decode(k.k, ptrs, p, entry) { - struct bpos alloc_pos2; - struct bch_backpointer bp2; - - bch2_pointer_to_bucket_and_backpointer(c, bp.btree_id, bp.level, - k, p, &alloc_pos2, &bp2); - if (!bpos_cmp(alloc_pos, alloc_pos2) && - !memcmp(&bp, &bp2, sizeof(bp))) - return k; - } + if (backpointer_matches_key(c, alloc_pos, bp, k)) + return k; backpointer_not_found(trans, alloc_pos, bp_offset, bp, k, "extent"); @@ -513,9 +526,6 @@ struct btree *bch2_backpointer_get_node(struct btree_trans *trans, struct bch_backpointer bp) { struct bch_fs *c = trans->c; - struct bkey_ptrs_c ptrs; - const union bch_extent_entry *entry; - struct extent_ptr_decoded p; struct btree *b; struct bkey_s_c k; @@ -533,25 +543,14 @@ struct btree *bch2_backpointer_get_node(struct btree_trans *trans, return b; } - /* Check if key matches backpointer: */ - k = bkey_i_to_s_c(&b->key); - ptrs = bch2_bkey_ptrs_c(k); - bkey_for_each_ptr_decode(k.k, ptrs, p, entry) { - struct bpos alloc_pos2; - struct bch_backpointer bp2; - - bch2_pointer_to_bucket_and_backpointer(c, bp.btree_id, bp.level, - k, p, &alloc_pos2, &bp2); - if (!bpos_cmp(alloc_pos, alloc_pos2) && - !memcmp(&bp, &bp2, sizeof(bp))) - return b; - } + if (backpointer_matches_key(c, alloc_pos, bp, + bkey_i_to_s_c(&b->key))) + return b; - if (btree_node_will_make_reachable(b)) - goto out; + if (!btree_node_will_make_reachable(b)) + backpointer_not_found(trans, alloc_pos, bp_offset, + bp, k, "btree node"); - backpointer_not_found(trans, alloc_pos, bp_offset, bp, k, "btree node"); -out: bch2_trans_iter_exit(trans, iter); return NULL; } |