bcachefs: Add persistent identifiers for recovery passes
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 29 Dec 2023 19:40:03 +0000 (14:40 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 1 Jan 2024 16:47:07 +0000 (11:47 -0500)
The next patch will start to refer to recovery passes from the
superblock; naturally, we now need identifiers that don't change, since
the existing enum is in the order in which they are run and is not
fixed.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/recovery.c
fs/bcachefs/recovery.h
fs/bcachefs/recovery_types.h

index c2f183d2ffe86fe9ae85c94ce774691b32b19430..6f8a84cc2c2eeb901af8603b44ae213a8d6f8138 100644 (file)
@@ -481,7 +481,7 @@ static int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
 }
 
 const char * const bch2_recovery_passes[] = {
-#define x(_fn, _when)  #_fn,
+#define x(_fn, ...)    #_fn,
        BCH_RECOVERY_PASSES()
 #undef x
        NULL
@@ -504,11 +504,41 @@ struct recovery_pass_fn {
 };
 
 static struct recovery_pass_fn recovery_pass_fns[] = {
-#define x(_fn, _when)  { .fn = bch2_##_fn, .when = _when },
+#define x(_fn, _id, _when)     { .fn = bch2_##_fn, .when = _when },
        BCH_RECOVERY_PASSES()
 #undef x
 };
 
+u64 bch2_recovery_passes_to_stable(u64 v)
+{
+       static const u8 map[] = {
+#define x(n, id, ...)  [BCH_RECOVERY_PASS_##n] = BCH_RECOVERY_PASS_STABLE_##n,
+       BCH_RECOVERY_PASSES()
+#undef x
+       };
+
+       u64 ret = 0;
+       for (unsigned i = 0; i < ARRAY_SIZE(map); i++)
+               if (v & BIT_ULL(i))
+                       ret |= BIT_ULL(map[i]);
+       return ret;
+}
+
+u64 bch2_recovery_passes_from_stable(u64 v)
+{
+       static const u8 map[] = {
+#define x(n, id, ...)  [BCH_RECOVERY_PASS_STABLE_##n] = BCH_RECOVERY_PASS_##n,
+       BCH_RECOVERY_PASSES()
+#undef x
+       };
+
+       u64 ret = 0;
+       for (unsigned i = 0; i < ARRAY_SIZE(map); i++)
+               if (v & BIT_ULL(i))
+                       ret |= BIT_ULL(map[i]);
+       return ret;
+}
+
 static void check_version_upgrade(struct bch_fs *c)
 {
        unsigned latest_compatible = bch2_latest_compatible_version(c->sb.version);
index d266aae90200e5d24340c905946f6108b15199aa..3a554b0751d01429ccb16c19440a46cb33d49979 100644 (file)
@@ -4,6 +4,9 @@
 
 extern const char * const bch2_recovery_passes[];
 
+u64 bch2_recovery_passes_to_stable(u64 v);
+u64 bch2_recovery_passes_from_stable(u64 v);
+
 /*
  * For when we need to rewind recovery passes and run a pass we skipped:
  */
index 515e3d62c2ac9ec481694985ddaa7b1722760d6f..d37c6fd30e3849bbc5135d3394536d4910e680fe 100644 (file)
@@ -7,45 +7,57 @@
 #define PASS_UNCLEAN           BIT(2)
 #define PASS_ALWAYS            BIT(3)
 
-#define BCH_RECOVERY_PASSES()                                                                  \
-       x(alloc_read,                   PASS_ALWAYS)                                            \
-       x(stripes_read,                 PASS_ALWAYS)                                            \
-       x(initialize_subvolumes,        0)                                                      \
-       x(snapshots_read,               PASS_ALWAYS)                                            \
-       x(check_topology,               0)                                                      \
-       x(check_allocations,            PASS_FSCK)                                              \
-       x(trans_mark_dev_sbs,           PASS_ALWAYS|PASS_SILENT)                                \
-       x(fs_journal_alloc,             PASS_ALWAYS|PASS_SILENT)                                \
-       x(set_may_go_rw,                PASS_ALWAYS|PASS_SILENT)                                \
-       x(journal_replay,               PASS_ALWAYS)                                            \
-       x(check_alloc_info,             PASS_FSCK)                                              \
-       x(check_lrus,                   PASS_FSCK)                                              \
-       x(check_btree_backpointers,     PASS_FSCK)                                              \
-       x(check_backpointers_to_extents,PASS_FSCK)                                              \
-       x(check_extents_to_backpointers,PASS_FSCK)                                              \
-       x(check_alloc_to_lru_refs,      PASS_FSCK)                                              \
-       x(fs_freespace_init,            PASS_ALWAYS|PASS_SILENT)                                \
-       x(bucket_gens_init,             0)                                                      \
-       x(check_snapshot_trees,         PASS_FSCK)                                              \
-       x(check_snapshots,              PASS_FSCK)                                              \
-       x(check_subvols,                PASS_FSCK)                                              \
-       x(delete_dead_snapshots,        PASS_FSCK)                                              \
-       x(fs_upgrade_for_subvolumes,    0)                                                      \
-       x(resume_logged_ops,            PASS_ALWAYS)                                            \
-       x(check_inodes,                 PASS_FSCK)                                              \
-       x(check_extents,                PASS_FSCK)                                              \
-       x(check_indirect_extents,       PASS_FSCK)                                              \
-       x(check_dirents,                PASS_FSCK)                                              \
-       x(check_xattrs,                 PASS_FSCK)                                              \
-       x(check_root,                   PASS_FSCK)                                              \
-       x(check_directory_structure,    PASS_FSCK)                                              \
-       x(check_nlinks,                 PASS_FSCK)                                              \
-       x(delete_dead_inodes,           PASS_FSCK|PASS_UNCLEAN)                                 \
-       x(fix_reflink_p,                0)                                                      \
-       x(set_fs_needs_rebalance,       0)                                                      \
+/*
+ * Passes may be reordered, but the second field is a persistent identifier and
+ * must never change:
+ */
+#define BCH_RECOVERY_PASSES()                                                  \
+       x(alloc_read,                            0, PASS_ALWAYS)                \
+       x(stripes_read,                          1, PASS_ALWAYS)                \
+       x(initialize_subvolumes,                 2, 0)                          \
+       x(snapshots_read,                        3, PASS_ALWAYS)                \
+       x(check_topology,                        4, 0)                          \
+       x(check_allocations,                     5, PASS_FSCK)                  \
+       x(trans_mark_dev_sbs,                    6, PASS_ALWAYS|PASS_SILENT)    \
+       x(fs_journal_alloc,                      7, PASS_ALWAYS|PASS_SILENT)    \
+       x(set_may_go_rw,                         8, PASS_ALWAYS|PASS_SILENT)    \
+       x(journal_replay,                        9, PASS_ALWAYS)                \
+       x(check_alloc_info,                     10, PASS_FSCK)                  \
+       x(check_lrus,                           11, PASS_FSCK)                  \
+       x(check_btree_backpointers,             12, PASS_FSCK)                  \
+       x(check_backpointers_to_extents,        13, PASS_FSCK)                  \
+       x(check_extents_to_backpointers,        14, PASS_FSCK)                  \
+       x(check_alloc_to_lru_refs,              15, PASS_FSCK)                  \
+       x(fs_freespace_init,                    16, PASS_ALWAYS|PASS_SILENT)    \
+       x(bucket_gens_init,                     17, 0)                          \
+       x(check_snapshot_trees,                 18, PASS_FSCK)                  \
+       x(check_snapshots,                      19, PASS_FSCK)                  \
+       x(check_subvols,                        20, PASS_FSCK)                  \
+       x(delete_dead_snapshots,                21, PASS_FSCK)                  \
+       x(fs_upgrade_for_subvolumes,            22, 0)                          \
+       x(resume_logged_ops,                    23, PASS_ALWAYS)                \
+       x(check_inodes,                         24, PASS_FSCK)                  \
+       x(check_extents,                        25, PASS_FSCK)                  \
+       x(check_indirect_extents,               26, PASS_FSCK)                  \
+       x(check_dirents,                        27, PASS_FSCK)                  \
+       x(check_xattrs,                         28, PASS_FSCK)                  \
+       x(check_root,                           29, PASS_FSCK)                  \
+       x(check_directory_structure,            30, PASS_FSCK)                  \
+       x(check_nlinks,                         31, PASS_FSCK)                  \
+       x(delete_dead_inodes,                   32, PASS_FSCK|PASS_UNCLEAN)     \
+       x(fix_reflink_p,                        33, 0)                          \
+       x(set_fs_needs_rebalance,               34, 0)                          \
 
+/* We normally enumerate recovery passes in the order we run them: */
 enum bch_recovery_pass {
-#define x(n, when)     BCH_RECOVERY_PASS_##n,
+#define x(n, id, when) BCH_RECOVERY_PASS_##n,
+       BCH_RECOVERY_PASSES()
+#undef x
+};
+
+/* But we also need stable identifiers that can be used in the superblock */
+enum bch_recovery_pass_stable {
+#define x(n, id, when) BCH_RECOVERY_PASS_STABLE_##n = id,
        BCH_RECOVERY_PASSES()
 #undef x
 };