#ifndef _BCACHEFS_RECOVERY_H
#define _BCACHEFS_RECOVERY_H
-#define for_each_journal_key(keys, i) \
- for (i = (keys).d; i < (keys).d + (keys).nr; (i)++)
+extern const char * const bch2_recovery_passes[];
-struct journal_iter {
- enum btree_id btree_id;
- unsigned level;
- struct journal_keys *keys;
- struct journal_key *k;
-};
+u64 bch2_recovery_passes_to_stable(u64 v);
+u64 bch2_recovery_passes_from_stable(u64 v);
/*
- * Iterate over keys in the btree, with keys from the journal overlaid on top:
+ * For when we need to rewind recovery passes and run a pass we skipped:
*/
-
-struct btree_and_journal_iter {
- struct btree_iter *btree;
-
- struct btree *b;
- struct btree_node_iter node_iter;
- struct bkey unpacked;
-
- struct journal_iter journal;
-
- enum last_key_returned {
- none,
- btree,
- journal,
- } last;
-};
-
-void bch2_btree_and_journal_iter_advance(struct btree_and_journal_iter *);
-struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *);
-struct bkey_s_c bch2_btree_and_journal_iter_next(struct btree_and_journal_iter *);
-
-void bch2_btree_and_journal_iter_init(struct btree_and_journal_iter *,
- struct btree_trans *,
- struct journal_keys *,
- enum btree_id, struct bpos);
-void bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter *,
- struct journal_keys *,
- struct btree *);
-
-typedef int (*btree_walk_node_fn)(struct bch_fs *c, struct btree *b);
-typedef int (*btree_walk_key_fn)(struct bch_fs *c, enum btree_id id,
- unsigned level, struct bkey_s_c k);
-
-int bch2_btree_and_journal_walk(struct bch_fs *, struct journal_keys *, enum btree_id,
- btree_walk_node_fn, btree_walk_key_fn);
-
-void bch2_journal_keys_free(struct journal_keys *);
-void bch2_journal_entries_free(struct list_head *);
+static inline int bch2_run_explicit_recovery_pass(struct bch_fs *c,
+ enum bch_recovery_pass pass)
+{
+ if (c->recovery_passes_explicit & BIT_ULL(pass))
+ return 0;
+
+ bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)",
+ bch2_recovery_passes[pass], pass,
+ bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass);
+
+ c->recovery_passes_explicit |= BIT_ULL(pass);
+
+ if (c->curr_recovery_pass >= pass) {
+ c->curr_recovery_pass = pass;
+ c->recovery_passes_complete &= (1ULL << pass) >> 1;
+ return -BCH_ERR_restart_recovery;
+ } else {
+ return 0;
+ }
+}
+
+int bch2_run_online_recovery_passes(struct bch_fs *);
+u64 bch2_fsck_recovery_passes(void);
int bch2_fs_recovery(struct bch_fs *);
int bch2_fs_initialize(struct bch_fs *);