Commit 808c680f authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Add persistent identifiers for recovery passes



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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 560661d4
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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:
 */
+49 −37
Original line number Diff line number Diff line
@@ -7,45 +7,57 @@
#define PASS_UNCLEAN		BIT(2)
#define PASS_ALWAYS		BIT(3)

/*
 * Passes may be reordered, but the second field is a persistent identifier and
 * must never change:
 */
#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)							\
	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
};