Lines Matching +full:pass +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
22 #include "super-io.h"
31 /* Fake recovery pass, so that scan_for_btree_nodes isn't 0: */
39 struct journal_keys *keys = &c->journal_keys; in bch2_set_may_go_rw()
43 * setting journal_key->overwritten: it will be accessed by multiple in bch2_set_may_go_rw()
46 move_gap(keys, keys->nr); in bch2_set_may_go_rw()
48 set_bit(BCH_FS_may_go_rw, &c->flags); in bch2_set_may_go_rw()
50 if (keys->nr || !c->opts.read_only || c->opts.fsck || !c->sb.clean || c->opts.recovery_passes) in bch2_set_may_go_rw()
72 static enum bch_recovery_pass_stable bch2_recovery_pass_to_stable(enum bch_recovery_pass pass) in bch2_recovery_pass_to_stable() argument
74 return passes_to_stable_map[pass]; in bch2_recovery_pass_to_stable()
102 * For when we need to rewind recovery passes and run a pass we skipped:
105 enum bch_recovery_pass pass) in __bch2_run_explicit_recovery_pass() argument
107 if (c->curr_recovery_pass == ARRAY_SIZE(recovery_pass_fns)) in __bch2_run_explicit_recovery_pass()
108 return -BCH_ERR_not_in_recovery; in __bch2_run_explicit_recovery_pass()
110 if (c->recovery_passes_complete & BIT_ULL(pass)) in __bch2_run_explicit_recovery_pass()
113 bool print = !(c->opts.recovery_passes & BIT_ULL(pass)); in __bch2_run_explicit_recovery_pass()
115 if (pass < BCH_RECOVERY_PASS_set_may_go_rw && in __bch2_run_explicit_recovery_pass()
116 c->curr_recovery_pass >= BCH_RECOVERY_PASS_set_may_go_rw) { in __bch2_run_explicit_recovery_pass()
118 bch_info(c, "need recovery pass %s (%u), but already rw", in __bch2_run_explicit_recovery_pass()
119 bch2_recovery_passes[pass], pass); in __bch2_run_explicit_recovery_pass()
120 return -BCH_ERR_cannot_rewind_recovery; in __bch2_run_explicit_recovery_pass()
124 bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)", in __bch2_run_explicit_recovery_pass()
125 bch2_recovery_passes[pass], pass, in __bch2_run_explicit_recovery_pass()
126 bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass); in __bch2_run_explicit_recovery_pass()
128 c->opts.recovery_passes |= BIT_ULL(pass); in __bch2_run_explicit_recovery_pass()
130 if (c->curr_recovery_pass > pass) { in __bch2_run_explicit_recovery_pass()
131 c->next_recovery_pass = pass; in __bch2_run_explicit_recovery_pass()
132 c->recovery_passes_complete &= (1ULL << pass) >> 1; in __bch2_run_explicit_recovery_pass()
133 return -BCH_ERR_restart_recovery; in __bch2_run_explicit_recovery_pass()
140 enum bch_recovery_pass pass) in bch2_run_explicit_recovery_pass() argument
143 spin_lock_irqsave(&c->recovery_pass_lock, flags); in bch2_run_explicit_recovery_pass()
144 int ret = __bch2_run_explicit_recovery_pass(c, pass); in bch2_run_explicit_recovery_pass()
145 spin_unlock_irqrestore(&c->recovery_pass_lock, flags); in bch2_run_explicit_recovery_pass()
150 enum bch_recovery_pass pass) in bch2_run_explicit_recovery_pass_persistent_locked() argument
152 lockdep_assert_held(&c->sb_lock); in bch2_run_explicit_recovery_pass_persistent_locked()
154 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); in bch2_run_explicit_recovery_pass_persistent_locked()
155 __set_bit_le64(bch2_recovery_pass_to_stable(pass), ext->recovery_passes_required); in bch2_run_explicit_recovery_pass_persistent_locked()
157 return bch2_run_explicit_recovery_pass(c, pass); in bch2_run_explicit_recovery_pass_persistent_locked()
161 enum bch_recovery_pass pass) in bch2_run_explicit_recovery_pass_persistent() argument
163 enum bch_recovery_pass_stable s = bch2_recovery_pass_to_stable(pass); in bch2_run_explicit_recovery_pass_persistent()
165 mutex_lock(&c->sb_lock); in bch2_run_explicit_recovery_pass_persistent()
166 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); in bch2_run_explicit_recovery_pass_persistent()
168 if (!test_bit_le64(s, ext->recovery_passes_required)) { in bch2_run_explicit_recovery_pass_persistent()
169 __set_bit_le64(s, ext->recovery_passes_required); in bch2_run_explicit_recovery_pass_persistent()
172 mutex_unlock(&c->sb_lock); in bch2_run_explicit_recovery_pass_persistent()
174 return bch2_run_explicit_recovery_pass(c, pass); in bch2_run_explicit_recovery_pass_persistent()
178 enum bch_recovery_pass pass) in bch2_clear_recovery_pass_required() argument
180 enum bch_recovery_pass_stable s = bch2_recovery_pass_to_stable(pass); in bch2_clear_recovery_pass_required()
182 mutex_lock(&c->sb_lock); in bch2_clear_recovery_pass_required()
183 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); in bch2_clear_recovery_pass_required()
185 if (test_bit_le64(s, ext->recovery_passes_required)) { in bch2_clear_recovery_pass_required()
186 __clear_bit_le64(s, ext->recovery_passes_required); in bch2_clear_recovery_pass_required()
189 mutex_unlock(&c->sb_lock); in bch2_clear_recovery_pass_required()
202 static bool should_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass) in should_run_recovery_pass() argument
204 struct recovery_pass_fn *p = recovery_pass_fns + pass; in should_run_recovery_pass()
206 if (c->opts.recovery_passes_exclude & BIT_ULL(pass)) in should_run_recovery_pass()
208 if (c->opts.recovery_passes & BIT_ULL(pass)) in should_run_recovery_pass()
210 if ((p->when & PASS_FSCK) && c->opts.fsck) in should_run_recovery_pass()
212 if ((p->when & PASS_UNCLEAN) && !c->sb.clean) in should_run_recovery_pass()
214 if (p->when & PASS_ALWAYS) in should_run_recovery_pass()
219 static int bch2_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass) in bch2_run_recovery_pass() argument
221 struct recovery_pass_fn *p = recovery_pass_fns + pass; in bch2_run_recovery_pass()
224 if (!(p->when & PASS_SILENT)) in bch2_run_recovery_pass()
226 bch2_recovery_passes[pass]); in bch2_run_recovery_pass()
227 ret = p->fn(c); in bch2_run_recovery_pass()
230 if (!(p->when & PASS_SILENT)) in bch2_run_recovery_pass()
241 if (!(p->when & PASS_ONLINE)) in bch2_run_online_recovery_passes()
246 i = c->curr_recovery_pass; in bch2_run_online_recovery_passes()
264 c->opts.recovery_passes_exclude &= ~BCH_RECOVERY_PASS_set_may_go_rw; in bch2_run_recovery_passes()
266 spin_lock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
268 while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns) && !ret) { in bch2_run_recovery_passes()
269 unsigned prev_done = c->recovery_pass_done; in bch2_run_recovery_passes()
270 unsigned pass = c->curr_recovery_pass; in bch2_run_recovery_passes() local
272 c->next_recovery_pass = pass + 1; in bch2_run_recovery_passes()
274 if (c->opts.recovery_pass_last && in bch2_run_recovery_passes()
275 c->curr_recovery_pass > c->opts.recovery_pass_last) in bch2_run_recovery_passes()
278 if (should_run_recovery_pass(c, pass)) { in bch2_run_recovery_passes()
279 spin_unlock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
280 ret = bch2_run_recovery_pass(c, pass) ?: in bch2_run_recovery_passes()
281 bch2_journal_flush(&c->journal); in bch2_run_recovery_passes()
283 if (!ret && !test_bit(BCH_FS_error, &c->flags)) in bch2_run_recovery_passes()
284 bch2_clear_recovery_pass_required(c, pass); in bch2_run_recovery_passes()
285 spin_lock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
287 if (c->next_recovery_pass < c->curr_recovery_pass) { in bch2_run_recovery_passes()
290 * can't always catch -BCH_ERR_restart_recovery because in bch2_run_recovery_passes()
295 c->recovery_passes_complete &= ~(~0ULL << c->curr_recovery_pass); in bch2_run_recovery_passes()
297 c->recovery_passes_complete |= BIT_ULL(pass); in bch2_run_recovery_passes()
298 c->recovery_pass_done = max(c->recovery_pass_done, pass); in bch2_run_recovery_passes()
302 c->curr_recovery_pass = c->next_recovery_pass; in bch2_run_recovery_passes()
305 c->recovery_pass_done > BCH_RECOVERY_PASS_check_snapshots) { in bch2_run_recovery_passes()
311 spin_unlock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()