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

1 // SPDX-License-Identifier: GPL-2.0
21 #include "super-io.h"
30 /* Fake recovery pass, so that scan_for_btree_nodes isn't 0: */
38 struct journal_keys *keys = &c->journal_keys; in bch2_set_may_go_rw()
42 * setting journal_key->overwritten: it will be accessed by multiple in bch2_set_may_go_rw()
45 move_gap(keys, keys->nr); in bch2_set_may_go_rw()
47 set_bit(BCH_FS_may_go_rw, &c->flags); in bch2_set_may_go_rw()
49 if (keys->nr || !c->opts.read_only || c->opts.fsck || !c->sb.clean || c->opts.recovery_passes) in bch2_set_may_go_rw()
71 static enum bch_recovery_pass_stable bch2_recovery_pass_to_stable(enum bch_recovery_pass pass) in bch2_recovery_pass_to_stable() argument
73 return passes_to_stable_map[pass]; in bch2_recovery_pass_to_stable()
101 * For when we need to rewind recovery passes and run a pass we skipped:
104 enum bch_recovery_pass pass) in __bch2_run_explicit_recovery_pass() argument
106 if (c->curr_recovery_pass == ARRAY_SIZE(recovery_pass_fns)) in __bch2_run_explicit_recovery_pass()
107 return -BCH_ERR_not_in_recovery; in __bch2_run_explicit_recovery_pass()
109 if (c->recovery_passes_complete & BIT_ULL(pass)) in __bch2_run_explicit_recovery_pass()
112 bool print = !(c->opts.recovery_passes & BIT_ULL(pass)); in __bch2_run_explicit_recovery_pass()
114 if (pass < BCH_RECOVERY_PASS_set_may_go_rw && in __bch2_run_explicit_recovery_pass()
115 c->curr_recovery_pass >= BCH_RECOVERY_PASS_set_may_go_rw) { in __bch2_run_explicit_recovery_pass()
117 bch_info(c, "need recovery pass %s (%u), but already rw", in __bch2_run_explicit_recovery_pass()
118 bch2_recovery_passes[pass], pass); in __bch2_run_explicit_recovery_pass()
119 return -BCH_ERR_cannot_rewind_recovery; in __bch2_run_explicit_recovery_pass()
123 bch_info(c, "running explicit recovery pass %s (%u), currently at %s (%u)", in __bch2_run_explicit_recovery_pass()
124 bch2_recovery_passes[pass], pass, in __bch2_run_explicit_recovery_pass()
125 bch2_recovery_passes[c->curr_recovery_pass], c->curr_recovery_pass); in __bch2_run_explicit_recovery_pass()
127 c->opts.recovery_passes |= BIT_ULL(pass); in __bch2_run_explicit_recovery_pass()
129 if (c->curr_recovery_pass > pass) { in __bch2_run_explicit_recovery_pass()
130 c->next_recovery_pass = pass; in __bch2_run_explicit_recovery_pass()
131 c->recovery_passes_complete &= (1ULL << pass) >> 1; in __bch2_run_explicit_recovery_pass()
132 return -BCH_ERR_restart_recovery; in __bch2_run_explicit_recovery_pass()
139 enum bch_recovery_pass pass) in bch2_run_explicit_recovery_pass() argument
142 spin_lock_irqsave(&c->recovery_pass_lock, flags); in bch2_run_explicit_recovery_pass()
143 int ret = __bch2_run_explicit_recovery_pass(c, pass); in bch2_run_explicit_recovery_pass()
144 spin_unlock_irqrestore(&c->recovery_pass_lock, flags); in bch2_run_explicit_recovery_pass()
149 enum bch_recovery_pass pass) in bch2_run_explicit_recovery_pass_persistent_locked() argument
151 lockdep_assert_held(&c->sb_lock); in bch2_run_explicit_recovery_pass_persistent_locked()
153 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); in bch2_run_explicit_recovery_pass_persistent_locked()
154 __set_bit_le64(bch2_recovery_pass_to_stable(pass), ext->recovery_passes_required); in bch2_run_explicit_recovery_pass_persistent_locked()
156 return bch2_run_explicit_recovery_pass(c, pass); in bch2_run_explicit_recovery_pass_persistent_locked()
160 enum bch_recovery_pass pass) in bch2_run_explicit_recovery_pass_persistent() argument
162 enum bch_recovery_pass_stable s = bch2_recovery_pass_to_stable(pass); in bch2_run_explicit_recovery_pass_persistent()
164 mutex_lock(&c->sb_lock); in bch2_run_explicit_recovery_pass_persistent()
165 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); in bch2_run_explicit_recovery_pass_persistent()
167 if (!test_bit_le64(s, ext->recovery_passes_required)) { in bch2_run_explicit_recovery_pass_persistent()
168 __set_bit_le64(s, ext->recovery_passes_required); in bch2_run_explicit_recovery_pass_persistent()
171 mutex_unlock(&c->sb_lock); in bch2_run_explicit_recovery_pass_persistent()
173 return bch2_run_explicit_recovery_pass(c, pass); in bch2_run_explicit_recovery_pass_persistent()
177 enum bch_recovery_pass pass) in bch2_clear_recovery_pass_required() argument
179 enum bch_recovery_pass_stable s = bch2_recovery_pass_to_stable(pass); in bch2_clear_recovery_pass_required()
181 mutex_lock(&c->sb_lock); in bch2_clear_recovery_pass_required()
182 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); in bch2_clear_recovery_pass_required()
184 if (test_bit_le64(s, ext->recovery_passes_required)) { in bch2_clear_recovery_pass_required()
185 __clear_bit_le64(s, ext->recovery_passes_required); in bch2_clear_recovery_pass_required()
188 mutex_unlock(&c->sb_lock); in bch2_clear_recovery_pass_required()
201 static bool should_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass) in should_run_recovery_pass() argument
203 struct recovery_pass_fn *p = recovery_pass_fns + pass; in should_run_recovery_pass()
205 if (c->opts.recovery_passes_exclude & BIT_ULL(pass)) in should_run_recovery_pass()
207 if (c->opts.recovery_passes & BIT_ULL(pass)) in should_run_recovery_pass()
209 if ((p->when & PASS_FSCK) && c->opts.fsck) in should_run_recovery_pass()
211 if ((p->when & PASS_UNCLEAN) && !c->sb.clean) in should_run_recovery_pass()
213 if (p->when & PASS_ALWAYS) in should_run_recovery_pass()
218 static int bch2_run_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass) in bch2_run_recovery_pass() argument
220 struct recovery_pass_fn *p = recovery_pass_fns + pass; in bch2_run_recovery_pass()
223 if (!(p->when & PASS_SILENT)) in bch2_run_recovery_pass()
225 bch2_recovery_passes[pass]); in bch2_run_recovery_pass()
226 ret = p->fn(c); in bch2_run_recovery_pass()
229 if (!(p->when & PASS_SILENT)) in bch2_run_recovery_pass()
239 down_read(&c->state_lock); in bch2_run_online_recovery_passes()
244 if (!(p->when & PASS_ONLINE)) in bch2_run_online_recovery_passes()
249 i = c->curr_recovery_pass; in bch2_run_online_recovery_passes()
256 up_read(&c->state_lock); in bch2_run_online_recovery_passes()
269 c->opts.recovery_passes_exclude &= ~BCH_RECOVERY_PASS_set_may_go_rw; in bch2_run_recovery_passes()
271 while (c->curr_recovery_pass < ARRAY_SIZE(recovery_pass_fns) && !ret) { in bch2_run_recovery_passes()
272 c->next_recovery_pass = c->curr_recovery_pass + 1; in bch2_run_recovery_passes()
274 spin_lock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
275 unsigned pass = c->curr_recovery_pass; in bch2_run_recovery_passes() local
277 if (c->opts.recovery_pass_last && in bch2_run_recovery_passes()
278 c->curr_recovery_pass > c->opts.recovery_pass_last) { in bch2_run_recovery_passes()
279 spin_unlock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
283 if (!should_run_recovery_pass(c, pass)) { in bch2_run_recovery_passes()
284 c->curr_recovery_pass++; in bch2_run_recovery_passes()
285 c->recovery_pass_done = max(c->recovery_pass_done, pass); in bch2_run_recovery_passes()
286 spin_unlock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
289 spin_unlock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
291 ret = bch2_run_recovery_pass(c, pass) ?: in bch2_run_recovery_passes()
292 bch2_journal_flush(&c->journal); in bch2_run_recovery_passes()
294 if (!ret && !test_bit(BCH_FS_error, &c->flags)) in bch2_run_recovery_passes()
295 bch2_clear_recovery_pass_required(c, pass); in bch2_run_recovery_passes()
297 spin_lock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()
298 if (c->next_recovery_pass < c->curr_recovery_pass) { in bch2_run_recovery_passes()
301 * can't always catch -BCH_ERR_restart_recovery because in bch2_run_recovery_passes()
306 c->recovery_passes_complete &= ~(~0ULL << c->curr_recovery_pass); in bch2_run_recovery_passes()
308 c->recovery_passes_complete |= BIT_ULL(pass); in bch2_run_recovery_passes()
309 c->recovery_pass_done = max(c->recovery_pass_done, pass); in bch2_run_recovery_passes()
311 c->curr_recovery_pass = c->next_recovery_pass; in bch2_run_recovery_passes()
312 spin_unlock_irq(&c->recovery_pass_lock); in bch2_run_recovery_passes()