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;
}
!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);
bch2_trans_iter_init(trans, &lru_iter, BTREE_ID_lru,
POS(ca->dev_idx, 0), 0);
+next_lru:
k = bch2_btree_iter_peek(&lru_iter);
ret = bkey_err(k);
if (ret)
if (!k.k || k.k->p.inode != ca->dev_idx)
goto out;
- if (bch2_trans_inconsistent_on(k.k->type != KEY_TYPE_lru, trans,
- "non lru key in lru btree"))
- goto out;
+ if (k.k->type != KEY_TYPE_lru) {
+ pr_buf(&buf, "non lru key in lru btree:\n ");
+ bch2_bkey_val_to_text(&buf, c, k);
+
+ if (!test_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags)) {
+ bch_err(c, "%s", buf.buf);
+ bch2_btree_iter_advance(&lru_iter);
+ goto next_lru;
+ } else {
+ bch2_trans_inconsistent(trans, "%s", buf.buf);
+ ret = -EINVAL;
+ goto out;
+ }
+ }
idx = k.k->p.offset;
bucket = le64_to_cpu(bkey_s_c_to_lru(k).v->idx);
if (idx != alloc_lru_idx(a->v)) {
pr_buf(&buf, "alloc key does not point back to lru entry when invalidating bucket:\n ");
-
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&a->k_i));
pr_buf(&buf, "\n ");
bch2_bkey_val_to_text(&buf, c, k);
- bch2_trans_inconsistent(trans, "%s", buf.buf);
- ret = -EINVAL;
- goto out;
+
+ if (!test_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags)) {
+ bch_err(c, "%s", buf.buf);
+ bch2_btree_iter_advance(&lru_iter);
+ goto next_lru;
+ } else {
+ bch2_trans_inconsistent(trans, "%s", buf.buf);
+ ret = -EINVAL;
+ goto out;
+ }
}
SET_BCH_ALLOC_V4_NEED_INC_GEN(&a->v, false);
if (ret)
return ret;
-
bkey_subvolume_init(&root_volume.k_i);
root_volume.k.p.offset = BCACHEFS_ROOT_SUBVOL;
root_volume.v.flags = 0;
}
}
+ 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");
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;
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;
goto err;
bch_verbose(c, "done checking allocations");
+ set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);
+
bch_info(c, "checking need_discard and freespace btrees");
err = "error checking need_discard and freespace btrees";
ret = bch2_check_alloc_info(c);
goto err;
bch_verbose(c, "done checking need_discard and freespace btrees");
+ 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);
if (ret)
goto err;
bch_verbose(c, "done checking lrus");
- }
- bch2_stripes_heap_start(c);
+ set_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags);
- set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);
- set_bit(BCH_FS_MAY_GO_RW, &c->flags);
-
- /*
- * 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);