summaryrefslogtreecommitdiff
path: root/libbcachefs/backpointers.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-11-30 02:20:42 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-11-30 02:20:51 -0500
commitf27b135285d032d9570a1accb00412e111b38878 (patch)
tree73da0a490f55cec0518d92e007e132803e467565 /libbcachefs/backpointers.c
parent3bd4653767bb5eadd253e382fe8503ceb6bef5d1 (diff)
Update bcachefs sources to 71a5b27e017d bcachefs: Make backpointer fsck wb flush check more rigorous
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'libbcachefs/backpointers.c')
-rw-r--r--libbcachefs/backpointers.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/libbcachefs/backpointers.c b/libbcachefs/backpointers.c
index 2fb96fa9..9b5f5809 100644
--- a/libbcachefs/backpointers.c
+++ b/libbcachefs/backpointers.c
@@ -3,6 +3,7 @@
#include "bbpos.h"
#include "alloc_background.h"
#include "backpointers.h"
+#include "bkey_buf.h"
#include "btree_cache.h"
#include "btree_update.h"
#include "btree_update_interior.h"
@@ -404,18 +405,13 @@ int bch2_check_btree_backpointers(struct bch_fs *c)
return ret;
}
-struct bpos_level {
- unsigned level;
- struct bpos pos;
-};
-
static int check_bp_exists(struct btree_trans *trans,
struct bpos bucket,
struct bch_backpointer bp,
struct bkey_s_c orig_k,
struct bpos bucket_start,
struct bpos bucket_end,
- struct bpos_level *last_flushed)
+ struct bkey_buf *last_flushed)
{
struct bch_fs *c = trans->c;
struct btree_iter bp_iter = { NULL };
@@ -439,14 +435,19 @@ static int check_bp_exists(struct btree_trans *trans,
if (bp_k.k->type != KEY_TYPE_backpointer ||
memcmp(bkey_s_c_to_backpointer(bp_k).v, &bp, sizeof(bp))) {
- if (last_flushed->level != bp.level ||
- !bpos_eq(last_flushed->pos, orig_k.k->p)) {
+ if (!bpos_eq(orig_k.k->p, last_flushed->k->k.p) ||
+ bkey_bytes(orig_k.k) != bkey_bytes(&last_flushed->k->k) ||
+ memcmp(orig_k.v, &last_flushed->k->v, bkey_val_bytes(orig_k.k))) {
+ if (bp.level) {
+ bch2_trans_unlock(trans);
+ bch2_btree_interior_updates_flush(c);
+ }
+
ret = bch2_btree_write_buffer_flush_sync(trans);
if (ret)
goto err;
- last_flushed->level = bp.level;
- last_flushed->pos = orig_k.k->p;
+ bch2_bkey_buf_reassemble(last_flushed, c, orig_k);
ret = -BCH_ERR_transaction_restart_write_buffer_flush;
goto out;
}
@@ -477,7 +478,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
enum btree_id btree, unsigned level,
struct bpos bucket_start,
struct bpos bucket_end,
- struct bpos_level *last_flushed,
+ struct bkey_buf *last_flushed,
struct bkey_s_c k)
{
struct bch_fs *c = trans->c;
@@ -511,7 +512,7 @@ static int check_btree_root_to_backpointers(struct btree_trans *trans,
enum btree_id btree_id,
struct bpos bucket_start,
struct bpos bucket_end,
- struct bpos_level *last_flushed,
+ struct bkey_buf *last_flushed,
int *level)
{
struct bch_fs *c = trans->c;
@@ -616,10 +617,13 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
struct btree_iter iter;
enum btree_id btree_id;
struct bkey_s_c k;
+ struct bkey_buf last_flushed;
int ret = 0;
+ bch2_bkey_buf_init(&last_flushed);
+ bkey_init(&last_flushed.k->k);
+
for (btree_id = 0; btree_id < btree_id_nr_alive(c); btree_id++) {
- struct bpos_level last_flushed = { UINT_MAX, POS_MIN };
int level, depth = btree_type_has_ptrs(btree_id) ? 0 : 1;
ret = commit_do(trans, NULL, NULL,
@@ -664,6 +668,7 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
}
}
+ bch2_bkey_buf_exit(&last_flushed, c);
return 0;
}