Skip to content

Commit 2635616

Browse files
author
Kent Overstreet
committed
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: Kent Overstreet <[email protected]>
1 parent dd22844 commit 2635616

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

fs/bcachefs/recovery.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,11 @@ int bch2_btree_lost_data(struct bch_fs *c,
9999
goto out;
100100
case BTREE_ID_snapshots:
101101
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_reconstruct_snapshots, 0) ?: ret;
102+
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_topology, 0) ?: ret;
102103
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes, 0) ?: ret;
103104
goto out;
104105
default:
106+
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_topology, 0) ?: ret;
105107
ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes, 0) ?: ret;
106108
goto out;
107109
}

fs/bcachefs/recovery_passes.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,13 @@ static bool recovery_pass_needs_set(struct bch_fs *c,
294294
enum bch_run_recovery_pass_flags *flags)
295295
{
296296
struct bch_fs_recovery *r = &c->recovery;
297-
bool in_recovery = test_bit(BCH_FS_in_recovery, &c->flags);
298-
bool persistent = !in_recovery || !(*flags & RUN_RECOVERY_PASS_nopersistent);
297+
298+
/*
299+
* Never run scan_for_btree_nodes persistently: check_topology will run
300+
* it if required
301+
*/
302+
if (pass == BCH_RECOVERY_PASS_scan_for_btree_nodes)
303+
*flags |= RUN_RECOVERY_PASS_nopersistent;
299304

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

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

344+
337345
lockdep_assert_held(&c->sb_lock);
338346

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

447455
int bch2_run_print_explicit_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass)
448456
{
449-
enum bch_run_recovery_pass_flags flags = RUN_RECOVERY_PASS_nopersistent;
457+
enum bch_run_recovery_pass_flags flags = 0;
450458

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

0 commit comments

Comments
 (0)