fixup bcachefs: New on disk format: Backpointers

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2023-02-12 14:25:59 -05:00
parent 53b1c6f44b
commit 7c057d3509

View file

@ -5,6 +5,7 @@
#include "backpointers.h" #include "backpointers.h"
#include "btree_cache.h" #include "btree_cache.h"
#include "btree_update.h" #include "btree_update.h"
#include "btree_write_buffer.h"
#include "error.h" #include "error.h"
#include <linux/mm.h> #include <linux/mm.h>
@ -553,7 +554,8 @@ static int check_bp_exists(struct btree_trans *trans,
struct bch_backpointer bp, struct bch_backpointer bp,
struct bkey_s_c orig_k, struct bkey_s_c orig_k,
struct bpos bucket_start, struct bpos bucket_start,
struct bpos bucket_end) struct bpos bucket_end,
struct bpos *last_flushed_pos)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct btree_iter alloc_iter, bp_iter = { NULL }; struct btree_iter alloc_iter, bp_iter = { NULL };
@ -597,8 +599,15 @@ static int check_bp_exists(struct btree_trans *trans,
goto err; goto err;
if (bp_k.k->type != KEY_TYPE_backpointer || if (bp_k.k->type != KEY_TYPE_backpointer ||
memcmp(bkey_s_c_to_backpointer(bp_k).v, &bp, sizeof(bp))) memcmp(bkey_s_c_to_backpointer(bp_k).v, &bp, sizeof(bp))) {
if (!bpos_eq(*last_flushed_pos, orig_k.k->p)) {
*last_flushed_pos = orig_k.k->p;
ret = bch2_btree_write_buffer_flush_sync(trans) ?:
-BCH_ERR_transaction_restart_write_buffer_flush;
goto out;
}
goto missing; goto missing;
}
out: out:
err: err:
fsck_err: fsck_err:
@ -607,6 +616,7 @@ static int check_bp_exists(struct btree_trans *trans,
printbuf_exit(&buf); printbuf_exit(&buf);
return ret; return ret;
missing: missing:
prt_printf(&buf, "missing backpointer for btree=%s l=%u ", prt_printf(&buf, "missing backpointer for btree=%s l=%u ",
bch2_btree_ids[bp.btree_id], bp.level); bch2_btree_ids[bp.btree_id], bp.level);
bch2_bkey_val_to_text(&buf, c, orig_k); bch2_bkey_val_to_text(&buf, c, orig_k);
@ -628,7 +638,8 @@ static int check_bp_exists(struct btree_trans *trans,
static int check_extent_to_backpointers(struct btree_trans *trans, static int check_extent_to_backpointers(struct btree_trans *trans,
struct btree_iter *iter, struct btree_iter *iter,
struct bpos bucket_start, struct bpos bucket_start,
struct bpos bucket_end) struct bpos bucket_end,
struct bpos *last_flushed_pos)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct bkey_ptrs_c ptrs; struct bkey_ptrs_c ptrs;
@ -655,7 +666,9 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
bch2_extent_ptr_to_bp(c, iter->btree_id, iter->path->level, bch2_extent_ptr_to_bp(c, iter->btree_id, iter->path->level,
k, p, &bucket_pos, &bp); k, p, &bucket_pos, &bp);
ret = check_bp_exists(trans, bucket_pos, bp, k, bucket_start, bucket_end); ret = check_bp_exists(trans, bucket_pos, bp, k,
bucket_start, bucket_end,
last_flushed_pos);
if (ret) if (ret)
return ret; return ret;
} }
@ -666,7 +679,8 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
static int check_btree_root_to_backpointers(struct btree_trans *trans, static int check_btree_root_to_backpointers(struct btree_trans *trans,
enum btree_id btree_id, enum btree_id btree_id,
struct bpos bucket_start, struct bpos bucket_start,
struct bpos bucket_end) struct bpos bucket_end,
struct bpos *last_flushed_pos)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct btree_iter iter; struct btree_iter iter;
@ -698,7 +712,9 @@ static int check_btree_root_to_backpointers(struct btree_trans *trans,
bch2_extent_ptr_to_bp(c, iter.btree_id, iter.path->level + 1, bch2_extent_ptr_to_bp(c, iter.btree_id, iter.path->level + 1,
k, p, &bucket_pos, &bp); k, p, &bucket_pos, &bp);
ret = check_bp_exists(trans, bucket_pos, bp, k, bucket_start, bucket_end); ret = check_bp_exists(trans, bucket_pos, bp, k,
bucket_start, bucket_end,
last_flushed_pos);
if (ret) if (ret)
goto err; goto err;
} }
@ -778,6 +794,7 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
{ {
struct btree_iter iter; struct btree_iter iter;
enum btree_id btree_id; enum btree_id btree_id;
struct bpos last_flushed_pos = SPOS_MAX;
int ret = 0; int ret = 0;
for (btree_id = 0; btree_id < BTREE_ID_NR; btree_id++) { for (btree_id = 0; btree_id < BTREE_ID_NR; btree_id++) {
@ -793,7 +810,8 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
BTREE_INSERT_LAZY_RW| BTREE_INSERT_LAZY_RW|
BTREE_INSERT_NOFAIL, BTREE_INSERT_NOFAIL,
check_extent_to_backpointers(trans, &iter, check_extent_to_backpointers(trans, &iter,
bucket_start, bucket_end)); bucket_start, bucket_end,
&last_flushed_pos));
if (ret) if (ret)
break; break;
} while (!bch2_btree_iter_advance(&iter)); } while (!bch2_btree_iter_advance(&iter));
@ -807,7 +825,8 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
BTREE_INSERT_LAZY_RW| BTREE_INSERT_LAZY_RW|
BTREE_INSERT_NOFAIL, BTREE_INSERT_NOFAIL,
check_btree_root_to_backpointers(trans, btree_id, check_btree_root_to_backpointers(trans, btree_id,
bucket_start, bucket_end)); bucket_start, bucket_end,
&last_flushed_pos));
if (ret) if (ret)
break; break;
} }