Commit 55936afe authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Flag btrees with missing data



We need this to know when we should attempt to reconstruct the snapshots
btree

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 43f5ea46
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -797,6 +797,7 @@ struct bch_fs {
		u64		features;
		u64		compat;
		unsigned long	errors_silent[BITS_TO_LONGS(BCH_SB_ERR_MAX)];
		u64		btrees_lost_data;
	}			sb;


+1 −0
Original line number Diff line number Diff line
@@ -818,6 +818,7 @@ struct bch_sb_field_ext {
	struct bch_sb_field	field;
	__le64			recovery_passes_required[2];
	__le64			errors_silent[8];
	__le64			btrees_lost_data;
};

struct bch_sb_field_downgrade_entry {
+9 −4
Original line number Diff line number Diff line
@@ -1264,10 +1264,12 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
	return retry_read;
fsck_err:
	if (ret == -BCH_ERR_btree_node_read_err_want_retry ||
	    ret == -BCH_ERR_btree_node_read_err_must_retry)
	    ret == -BCH_ERR_btree_node_read_err_must_retry) {
		retry_read = 1;
	else
	} else {
		set_btree_node_read_error(b);
		bch2_btree_lost_data(c, b->c.btree_id);
	}
	goto out;
}

@@ -1328,6 +1330,7 @@ static void btree_node_read_work(struct work_struct *work)

		if (!can_retry) {
			set_btree_node_read_error(b);
			bch2_btree_lost_data(c, b->c.btree_id);
			break;
		}
	}
@@ -1527,9 +1530,10 @@ static CLOSURE_CALLBACK(btree_node_read_all_replicas_done)
		ret = -1;
	}

	if (ret)
	if (ret) {
		set_btree_node_read_error(b);
	else if (*saw_error)
		bch2_btree_lost_data(c, b->c.btree_id);
	} else if (*saw_error)
		bch2_btree_node_rewrite_async(c, b);

	for (i = 0; i < ra->nr; i++) {
@@ -1665,6 +1669,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
			bch2_fatal_error(c);

		set_btree_node_read_error(b);
		bch2_btree_lost_data(c, b->c.btree_id);
		clear_btree_node_read_in_flight(b);
		wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
		printbuf_exit(&buf);
+23 −0
Original line number Diff line number Diff line
@@ -33,6 +33,20 @@

#define QSTR(n) { { { .len = strlen(n) } }, .name = n }

void bch2_btree_lost_data(struct bch_fs *c, enum btree_id btree)
{
	u64 b = BIT_ULL(btree);

	if (!(c->sb.btrees_lost_data & b)) {
		bch_err(c, "flagging btree %s lost data", bch2_btree_id_str(btree));

		mutex_lock(&c->sb_lock);
		bch2_sb_field_get(c->disk_sb.sb, ext)->btrees_lost_data |= cpu_to_le64(b);
		bch2_write_super(c);
		mutex_unlock(&c->sb_lock);
	}
}

static bool btree_id_is_alloc(enum btree_id id)
{
	switch (id) {
@@ -470,6 +484,7 @@ static int read_btree_roots(struct bch_fs *c)
			}

			ret = 0;
			bch2_btree_lost_data(c, i);
		}
	}

@@ -848,6 +863,14 @@ int bch2_fs_recovery(struct bch_fs *c)
		write_sb = true;
	}

	if (c->opts.fsck &&
	    !test_bit(BCH_FS_error, &c->flags) &&
	    c->recovery_pass_done == BCH_RECOVERY_PASS_NR - 1 &&
	    ext->btrees_lost_data) {
		ext->btrees_lost_data = 0;
		write_sb = true;
	}

	if (c->opts.fsck &&
	    !test_bit(BCH_FS_error, &c->flags) &&
	    !test_bit(BCH_FS_errors_not_fixed, &c->flags)) {
+2 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#ifndef _BCACHEFS_RECOVERY_H
#define _BCACHEFS_RECOVERY_H

void bch2_btree_lost_data(struct bch_fs *, enum btree_id);

int bch2_journal_replay(struct bch_fs *);

int bch2_fs_recovery(struct bch_fs *);
Loading