bcachefs: provide unlocked version of run_explicit_recovery_pass_persistent
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 26 Apr 2025 16:38:53 +0000 (12:38 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:36 +0000 (20:14 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/recovery.c
fs/bcachefs/recovery_passes.c
fs/bcachefs/recovery_passes.h
fs/bcachefs/super-io.c

index 8989ea4a3934d3da48bf3713fd95876021c5a017..0369dd656d324b4bebc34f9bbb659b0ffcf2d7e8 100644 (file)
@@ -844,6 +844,7 @@ struct bch_fs {
                unsigned        nsec_per_time_unit;
                u64             features;
                u64             compat;
+               u64             recovery_passes_required;
                unsigned long   errors_silent[BITS_TO_LONGS(BCH_FSCK_ERR_MAX)];
                u64             btrees_lost_data;
        }                       sb;
index d13a6df289c7c3351495c85411bee8197867845d..375111b56029eb0c11319e600a118a29289fc7c5 100644 (file)
@@ -52,24 +52,24 @@ int bch2_btree_lost_data(struct bch_fs *c,
        }
 
        /* Once we have runtime self healing for topology errors we won't need this: */
-       ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_topology) ?: ret;
+       ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_topology) ?: ret;
 
        /* Btree node accounting will be off: */
        __set_bit_le64(BCH_FSCK_ERR_accounting_mismatch, ext->errors_silent);
-       ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_allocations) ?: ret;
+       ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_allocations) ?: ret;
 
 #ifdef CONFIG_BCACHEFS_DEBUG
        /*
         * These are much more minor, and don't need to be corrected right away,
         * but in debug mode we want the next fsck run to be clean:
         */
-       ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_lrus) ?: ret;
-       ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_backpointers_to_extents) ?: ret;
+       ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_lrus) ?: ret;
+       ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_backpointers_to_extents) ?: ret;
 #endif
 
        switch (btree) {
        case BTREE_ID_alloc:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
 
                __set_bit_le64(BCH_FSCK_ERR_alloc_key_data_type_wrong, ext->errors_silent);
                __set_bit_le64(BCH_FSCK_ERR_alloc_key_gen_wrong, ext->errors_silent);
@@ -79,30 +79,30 @@ int bch2_btree_lost_data(struct bch_fs *c,
                __set_bit_le64(BCH_FSCK_ERR_alloc_key_stripe_redundancy_wrong, ext->errors_silent);
                goto out;
        case BTREE_ID_backpointers:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_btree_backpointers) ?: ret;
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_extents_to_backpointers) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_btree_backpointers) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_extents_to_backpointers) ?: ret;
                goto out;
        case BTREE_ID_need_discard:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
                goto out;
        case BTREE_ID_freespace:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
                goto out;
        case BTREE_ID_bucket_gens:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
                goto out;
        case BTREE_ID_lru:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_alloc_info) ?: ret;
                goto out;
        case BTREE_ID_accounting:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_allocations) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_check_allocations) ?: ret;
                goto out;
        case BTREE_ID_snapshots:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_reconstruct_snapshots) ?: ret;
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_reconstruct_snapshots) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes) ?: ret;
                goto out;
        default:
-               ret = bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes) ?: ret;
+               ret = __bch2_run_explicit_recovery_pass_persistent(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes) ?: ret;
                goto out;
        }
 out:
index 347e17fe7901a5f5c6e786dbb50ee2a92e047781..97af1e0629eb4b183793c6d27fde3bee0029f21f 100644 (file)
@@ -193,9 +193,9 @@ int bch2_run_explicit_recovery_pass(struct bch_fs *c,
        return ret;
 }
 
-int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *c,
-                                               struct printbuf *out,
-                                               enum bch_recovery_pass pass)
+int __bch2_run_explicit_recovery_pass_persistent(struct bch_fs *c,
+                                                struct printbuf *out,
+                                                enum bch_recovery_pass pass)
 {
        lockdep_assert_held(&c->sb_lock);
 
@@ -205,6 +205,20 @@ int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *c,
        return bch2_run_explicit_recovery_pass_printbuf(c, out, pass);
 }
 
+int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *c,
+                                              struct printbuf *out,
+                                              enum bch_recovery_pass pass)
+{
+       if (c->sb.recovery_passes_required & BIT_ULL(pass))
+               return 0;
+
+       mutex_lock(&c->sb_lock);
+       int ret = __bch2_run_explicit_recovery_pass_persistent(c, out, pass);
+       mutex_unlock(&c->sb_lock);
+
+       return ret;
+}
+
 static void bch2_clear_recovery_pass_required(struct bch_fs *c,
                                              enum bch_recovery_pass pass)
 {
index 1f91be4258c56624b282e2bb5df59aefc6638f1b..94fbc64e9b7ed2485fa9578b5b7ce18cf433efbf 100644 (file)
@@ -13,6 +13,8 @@ int bch2_run_explicit_recovery_pass_printbuf(struct bch_fs *,
                                    enum bch_recovery_pass);
 int bch2_run_explicit_recovery_pass(struct bch_fs *, enum bch_recovery_pass);
 
+int __bch2_run_explicit_recovery_pass_persistent(struct bch_fs *, struct printbuf *,
+                                              enum bch_recovery_pass);
 int bch2_run_explicit_recovery_pass_persistent(struct bch_fs *, struct printbuf *,
                                               enum bch_recovery_pass);
 
index d53cbc5f992595dd17fab3298f23c14fcfd3d97a..8730d2e78d1d8233a6560a642a5971c5e5ad7fb2 100644 (file)
@@ -623,6 +623,9 @@ static void bch2_sb_update(struct bch_fs *c)
 
        struct bch_sb_field_ext *ext = bch2_sb_field_get(src, ext);
        if (ext) {
+               c->sb.recovery_passes_required =
+                       bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0]));
+
                le_bitvector_to_cpu(c->sb.errors_silent, (void *) ext->errors_silent,
                                    sizeof(c->sb.errors_silent) * 8);
                c->sb.btrees_lost_data = le64_to_cpu(ext->btrees_lost_data);