- if (BCH_SB_INITIALIZED(c->disk_sb)) {
- ret = bch2_journal_read(c, &journal);
- if (ret)
- goto err;
-
- j = &list_entry(journal.prev, struct journal_replay, list)->j;
-
- c->prio_clock[READ].hand = le16_to_cpu(j->read_clock);
- c->prio_clock[WRITE].hand = le16_to_cpu(j->write_clock);
-
- for (i = 0; i < BTREE_ID_NR; i++) {
- unsigned level;
- struct bkey_i *k;
-
- err = "missing btree root";
- k = bch2_journal_find_btree_root(c, j, i, &level);
- if (!k && i < BTREE_ID_ALLOC)
- goto err;
-
- if (!k)
- continue;
-
- err = "error reading btree root";
- if (bch2_btree_root_read(c, i, k, level))
- goto err;
- }
-
- err = "error reading allocation information";
- ret = bch2_alloc_read(c, &journal);
- if (ret)
- goto err;
-
- bch_verbose(c, "starting mark and sweep:");
- err = "error in recovery";
- ret = bch2_initial_gc(c, &journal);
- if (ret)
- goto err;
- bch_verbose(c, "mark and sweep done");
-
- if (c->opts.noreplay)
- goto recovery_done;
-
- err = "cannot allocate new btree root";
- for (i = 0; i < BTREE_ID_NR; i++)
- if (!c->btree_roots[i].b &&
- bch2_btree_root_alloc(c, i, &cl))
- goto err;
-
- closure_sync(&cl);
-
- /*
- * bch2_journal_start() can't happen sooner, or btree_gc_finish()
- * will give spurious errors about oldest_gen > bucket_gen -
- * this is a hack but oh well.
- */
- bch2_journal_start(c);
-
- err = "error starting allocator thread";
- for_each_rw_member(ca, c, i)
- if (bch2_dev_allocator_start(ca)) {
- percpu_ref_put(&ca->io_ref);
- goto err;
- }
-
- bch_verbose(c, "starting journal replay:");
- err = "journal replay failed";
- ret = bch2_journal_replay(c, &journal);
- if (ret)
- goto err;
- bch_verbose(c, "journal replay done");
-
- if (c->opts.norecovery)
- goto recovery_done;
-
- bch_verbose(c, "starting fsck:");
- err = "error in fsck";
- ret = bch2_fsck(c, !c->opts.nofsck);
- if (ret)
- goto err;
- bch_verbose(c, "fsck done");
-
- for_each_rw_member(ca, c, i)
- if (ca->need_alloc_write) {
- ret = bch2_alloc_write(c, ca, &journal_seq);
- if (ret) {
- percpu_ref_put(&ca->io_ref);
- goto err;
- }
- }
-
- bch2_journal_flush_seq(&c->journal, journal_seq);
- } else {
- struct bch_inode_unpacked inode;
- struct bkey_inode_buf packed_inode;
-
- bch_notice(c, "initializing new filesystem");
-
- ret = bch2_initial_gc(c, &journal);
- if (ret)
- goto err;
-
- err = "unable to allocate journal buckets";
- for_each_rw_member(ca, c, i)
- if (bch2_dev_journal_alloc(ca)) {
- percpu_ref_put(&ca->io_ref);
- goto err;
- }
-
- err = "cannot allocate new btree root";
- for (i = 0; i < BTREE_ID_NR; i++)
- if (bch2_btree_root_alloc(c, i, &cl))
- goto err;
-
- /*
- * journal_res_get() will crash if called before this has
- * set up the journal.pin FIFO and journal.cur pointer:
- */
- bch2_journal_start(c);
- bch2_journal_set_replay_done(&c->journal);
-
- err = "error starting allocator thread";
- for_each_rw_member(ca, c, i)
- if (bch2_dev_allocator_start(ca)) {
- percpu_ref_put(&ca->io_ref);
- goto err;
- }
-
- /* Wait for new btree roots to be written: */
- closure_sync(&cl);
-
- bch2_inode_init(c, &inode, 0, 0,
- S_IFDIR|S_IRWXU|S_IRUGO|S_IXUGO, 0);
- inode.inum = BCACHE_ROOT_INO;
-
- bch2_inode_pack(&packed_inode, &inode);