diff options
author | 2023-12-31 19:41:45 -0500 | |
---|---|---|
committer | 2024-01-05 23:24:20 -0500 | |
commit | d55ddf6e7a81e1e72b2f73c3cca836a6961c68af (patch) | |
tree | 64236e2119de36ca0d778ac2870f4994621ccfbb | |
parent | bcachefs: bch2_trigger_pointer() (diff) | |
download | linux-d55ddf6e7a81e1e72b2f73c3cca836a6961c68af.tar.gz linux-d55ddf6e7a81e1e72b2f73c3cca836a6961c68af.tar.bz2 linux-d55ddf6e7a81e1e72b2f73c3cca836a6961c68af.zip |
bcachefs: Online fsck can now fix errors
BCH_FS_fsck_done -> BCH_FS_fsck_running; set when we might be fixing
fsck errors. Also; set fix_errors to ask by default when fsck is
running.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/bcachefs.h | 5 | ||||
-rw-r--r-- | fs/bcachefs/chardev.c | 11 | ||||
-rw-r--r-- | fs/bcachefs/error.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 7 |
4 files changed, 20 insertions, 11 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index ffef6182a477..c7ed097e41a7 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -602,9 +602,6 @@ struct bch_dev { }; /* - * fsck_done - kill? - * - * replace with something more general from enumated fsck passes/errors: * initial_gc_unfixed * error * topology error @@ -620,7 +617,7 @@ struct bch_dev { x(going_ro) \ x(write_disable_complete) \ x(clean_shutdown) \ - x(fsck_done) \ + x(fsck_running) \ x(initial_gc_unfixed) \ x(need_another_gc) \ x(need_delete_dead_snapshots) \ diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c index 46db563e0497..226b39c17667 100644 --- a/fs/bcachefs/chardev.c +++ b/fs/bcachefs/chardev.c @@ -774,15 +774,24 @@ static int bch2_fsck_online_thread_fn(void *arg) /* * XXX: can we figure out a way to do this without mucking with c->opts? */ + unsigned old_fix_errors = c->opts.fix_errors; if (opt_defined(thr->opts, fix_errors)) c->opts.fix_errors = thr->opts.fix_errors; + else + c->opts.fix_errors = FSCK_FIX_ask; + c->opts.fsck = true; + set_bit(BCH_FS_fsck_running, &c->flags); c->curr_recovery_pass = BCH_RECOVERY_PASS_check_alloc_info; - bch2_run_online_recovery_passes(c); + int ret = bch2_run_online_recovery_passes(c); + + clear_bit(BCH_FS_fsck_running, &c->flags); + bch_err_fn(c, ret); c->stdio = NULL; c->stdio_filter = NULL; + c->opts.fix_errors = old_fix_errors; thread_with_stdio_done(&thr->thr); diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index 8a8bcbcdff2a..e8200cad3ab8 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -28,7 +28,7 @@ bool bch2_inconsistent_error(struct bch_fs *c) void bch2_topology_error(struct bch_fs *c) { set_bit(BCH_FS_topology_error, &c->flags); - if (test_bit(BCH_FS_fsck_done, &c->flags)) + if (!test_bit(BCH_FS_fsck_running, &c->flags)) bch2_inconsistent_error(c); } @@ -141,7 +141,7 @@ static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt) { struct fsck_err_state *s; - if (test_bit(BCH_FS_fsck_done, &c->flags)) + if (!test_bit(BCH_FS_fsck_running, &c->flags)) return NULL; list_for_each_entry(s, &c->fsck_error_msgs, list) @@ -223,7 +223,7 @@ int bch2_fsck_err(struct bch_fs *c, prt_printf(out, bch2_log_msg(c, "")); #endif - if (test_bit(BCH_FS_fsck_done, &c->flags)) { + if (!test_bit(BCH_FS_fsck_running, &c->flags)) { if (c->opts.errors != BCH_ON_ERROR_continue || !(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE))) { prt_str(out, ", shutting down"); @@ -290,7 +290,7 @@ int bch2_fsck_err(struct bch_fs *c, bch2_print_string_as_lines(KERN_ERR, out->buf); } - if (!test_bit(BCH_FS_fsck_done, &c->flags) && + if (test_bit(BCH_FS_fsck_running, &c->flags) && (ret != -BCH_ERR_fsck_fix && ret != -BCH_ERR_fsck_ignore)) bch_err(c, "Unable to continue, halting"); diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index 066aef6f3c74..6c0af6502ce9 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -832,6 +832,9 @@ int bch2_fs_recovery(struct bch_fs *c) if (c->opts.fsck && IS_ENABLED(CONFIG_BCACHEFS_DEBUG)) c->recovery_passes_explicit |= BIT_ULL(BCH_RECOVERY_PASS_check_topology); + if (c->opts.fsck) + set_bit(BCH_FS_fsck_running, &c->flags); + ret = bch2_blacklist_table_initialize(c); if (ret) { bch_err(c, "error initializing blacklist table"); @@ -972,6 +975,8 @@ use_clean: if (ret) goto err; + clear_bit(BCH_FS_fsck_running, &c->flags); + /* If we fixed errors, verify that fs is actually clean now: */ if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG) && test_bit(BCH_FS_errors_fixed, &c->flags) && @@ -1066,7 +1071,6 @@ use_clean: ret = 0; out: - set_bit(BCH_FS_fsck_done, &c->flags); bch2_flush_fsck_errs(c); if (!c->opts.keep_journal && @@ -1113,7 +1117,6 @@ int bch2_fs_initialize(struct bch_fs *c) c->curr_recovery_pass = ARRAY_SIZE(recovery_pass_fns); set_bit(BCH_FS_may_go_rw, &c->flags); - set_bit(BCH_FS_fsck_done, &c->flags); for (unsigned i = 0; i < BTREE_ID_NR; i++) bch2_btree_root_alloc(c, i); |