diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-21 21:57:15 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-22 19:17:37 -0400 |
commit | 4233bfbbfe89795edf3022ddf447ff1e3e6da56f (patch) | |
tree | 8ade80ecbc0abceec7ec54465a33c61346cad461 | |
parent | e42ef1501da2b75a270a997113d0c0b79e3a4956 (diff) |
fixup! bcachefs: Go RW before bch2_check_lrus()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/alloc_background.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 82 |
3 files changed, 48 insertions, 39 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 5f52f279626a..32ebf6cc9e07 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -382,7 +382,8 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k, return -EINVAL; } - if (!a.v->io_time[READ]) { + if (!a.v->io_time[READ] && + test_bit(BCH_FS_CHECK_ALLOC_TO_LRU_REFS_DONE, &c->flags)) { pr_buf(err, "cached bucket with read_time == 0"); return -EINVAL; } @@ -588,7 +589,6 @@ int bch2_trans_mark_alloc(struct btree_trans *trans, !new_a->io_time[READ]) new_a->io_time[READ] = max_t(u64, 1, atomic64_read(&c->io_clock[READ].now)); - old_lru = alloc_lru_idx(old_a); new_lru = alloc_lru_idx(*new_a); diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index 45f7634ce529..2eced20667fa 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -509,6 +509,7 @@ enum { BCH_FS_TOPOLOGY_REPAIR_DONE, BCH_FS_INITIAL_GC_DONE, /* kill when we enumerate fsck passes */ BCH_FS_CHECK_LRUS_DONE, + BCH_FS_CHECK_ALLOC_TO_LRU_REFS_DONE, BCH_FS_FSCK_DONE, BCH_FS_INITIAL_GC_UNFIXED, /* kill when we enumerate fsck errors */ BCH_FS_NEED_ANOTHER_GC, diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index 5d9bbfe606c1..ff483ff303da 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1095,6 +1095,12 @@ int bch2_fs_recovery(struct bch_fs *c) } } + if (c->opts.fsck && c->opts.norecovery) { + bch_err(c, "cannot select both norecovery and fsck"); + ret = -EINVAL; + goto err; + } + ret = bch2_blacklist_table_initialize(c); if (ret) { bch_err(c, "error initializing blacklist table"); @@ -1188,6 +1194,13 @@ use_clean: if (ret) goto err; + /* + * Skip past versions that might have possibly been used (as nonces), + * but hadn't had their pointers written: + */ + if (c->sb.encryption_type && !c->sb.clean) + atomic64_add(1 << 16, &c->key_version); + ret = read_btree_roots(c); if (ret) goto err; @@ -1210,12 +1223,7 @@ use_clean: goto err; bch_verbose(c, "stripes_read done"); - /* - * If we're not running fsck, this ensures bch2_fsck_err() calls are - * instead interpreted as bch2_inconsistent_err() calls: - */ - if (!c->opts.fsck) - set_bit(BCH_FS_FSCK_DONE, &c->flags); + bch2_stripes_heap_start(c); if (c->opts.fsck) { bool metadata_only = c->opts.norecovery; @@ -1238,6 +1246,14 @@ use_clean: set_bit(BCH_FS_MAY_GO_RW, &c->flags); + bch_verbose(c, "starting journal replay, %zu keys", c->journal_keys.nr); + err = "journal replay failed"; + ret = bch2_journal_replay(c); + if (ret) + goto err; + if (c->opts.verbose || !c->sb.clean) + bch_info(c, "journal replay done"); + bch_info(c, "checking lrus"); err = "error checking lrus"; ret = bch2_check_lrus(c, true); @@ -1246,50 +1262,42 @@ use_clean: bch_verbose(c, "done checking lrus"); set_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags); - } else { - set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags); - set_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags); - set_bit(BCH_FS_MAY_GO_RW, &c->flags); - } - - bch2_stripes_heap_start(c); - /* - * Skip past versions that might have possibly been used (as nonces), - * but hadn't had their pointers written: - */ - if (c->sb.encryption_type && !c->sb.clean) - atomic64_add(1 << 16, &c->key_version); - - if (c->opts.norecovery) - goto out; - - bch_verbose(c, "starting journal replay, %zu keys", c->journal_keys.nr); - err = "journal replay failed"; - ret = bch2_journal_replay(c); - if (ret) - goto err; - if (c->opts.verbose || !c->sb.clean) - bch_info(c, "journal replay done"); - - err = "error initializing freespace"; - ret = bch2_fs_freespace_init(c); - if (ret) - goto err; - - if (c->opts.fsck) { bch_info(c, "checking alloc to lru refs"); err = "error checking alloc to lru refs"; ret = bch2_check_alloc_to_lru_refs(c); if (ret) goto err; + set_bit(BCH_FS_CHECK_ALLOC_TO_LRU_REFS_DONE, &c->flags); ret = bch2_check_lrus(c, true); if (ret) goto err; bch_verbose(c, "done checking alloc to lru refs"); + } else { + set_bit(BCH_FS_MAY_GO_RW, &c->flags); + set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags); + set_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags); + set_bit(BCH_FS_CHECK_ALLOC_TO_LRU_REFS_DONE, &c->flags); + set_bit(BCH_FS_FSCK_DONE, &c->flags); + + if (c->opts.norecovery) + goto out; + + bch_verbose(c, "starting journal replay, %zu keys", c->journal_keys.nr); + err = "journal replay failed"; + ret = bch2_journal_replay(c); + if (ret) + goto err; + if (c->opts.verbose || !c->sb.clean) + bch_info(c, "journal replay done"); } + err = "error initializing freespace"; + ret = bch2_fs_freespace_init(c); + if (ret) + goto err; + if (c->sb.version < bcachefs_metadata_version_snapshot_2) { bch2_fs_lazy_rw(c); |