Commit 26356164 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Don't persistently run scan_for_btree_nodes



bch2_btree_lost_data() gets called on btree node read error, but the
error might be transient.

btree_node_scan is expensive, and there's no need to run it persistently
(marking it in the superblock as required to run) - check_topology
will run it if required, via bch2_get_scanned_nodes().

Running it non-persistently is fine, to avoid check_topology having to
rewind recovery to run it.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent dd22844f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -99,9 +99,11 @@ int bch2_btree_lost_data(struct bch_fs *c,
		goto out;
	case BTREE_ID_snapshots:
		ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_reconstruct_snapshots, 0) ?: ret;
		ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_topology, 0) ?: ret;
		ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes, 0) ?: ret;
		goto out;
	default:
		ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_topology, 0) ?: ret;
		ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes, 0) ?: ret;
		goto out;
	}
+11 −3
Original line number Diff line number Diff line
@@ -294,8 +294,13 @@ static bool recovery_pass_needs_set(struct bch_fs *c,
				    enum bch_run_recovery_pass_flags *flags)
{
	struct bch_fs_recovery *r = &c->recovery;
	bool in_recovery = test_bit(BCH_FS_in_recovery, &c->flags);
	bool persistent = !in_recovery || !(*flags & RUN_RECOVERY_PASS_nopersistent);

	/*
	 * Never run scan_for_btree_nodes persistently: check_topology will run
	 * it if required
	 */
	if (pass == BCH_RECOVERY_PASS_scan_for_btree_nodes)
		*flags |= RUN_RECOVERY_PASS_nopersistent;

	if ((*flags & RUN_RECOVERY_PASS_ratelimit) &&
	    !bch2_recovery_pass_want_ratelimit(c, pass))
@@ -310,6 +315,8 @@ static bool recovery_pass_needs_set(struct bch_fs *c,
	 * Otherwise, we run run_explicit_recovery_pass when we find damage, so
	 * it should run again even if it's already run:
	 */
	bool in_recovery = test_bit(BCH_FS_in_recovery, &c->flags);
	bool persistent = !in_recovery || !(*flags & RUN_RECOVERY_PASS_nopersistent);

	if (persistent
	    ? !(c->sb.recovery_passes_required & BIT_ULL(pass))
@@ -334,6 +341,7 @@ int __bch2_run_explicit_recovery_pass(struct bch_fs *c,
	struct bch_fs_recovery *r = &c->recovery;
	int ret = 0;


	lockdep_assert_held(&c->sb_lock);

	bch2_printbuf_make_room(out, 1024);
@@ -446,7 +454,7 @@ int bch2_require_recovery_pass(struct bch_fs *c,

int bch2_run_print_explicit_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass)
{
	enum bch_run_recovery_pass_flags flags = RUN_RECOVERY_PASS_nopersistent;
	enum bch_run_recovery_pass_flags flags = 0;

	if (!recovery_pass_needs_set(c, pass, &flags))
		return 0;