]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/recovery.c
Update bcachefs sources to 6bb1ba5c94 bcachefs: Improve alloc_mem_to_key()
[bcachefs-tools-debian] / libbcachefs / recovery.c
index 64e0b542e7791d53cf0a0b5323e00e3e79656800..29fe6260ace5ad6c9ecb6d55765edd6a296f5382 100644 (file)
@@ -337,10 +337,11 @@ static void btree_and_journal_iter_prefetch(struct bch_fs *c, struct btree *b,
        bch2_bkey_buf_exit(&tmp, c);
 }
 
-static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b,
+static int bch2_btree_and_journal_walk_recurse(struct btree_trans *trans, struct btree *b,
                                enum btree_id btree_id,
                                btree_walk_key_fn key_fn)
 {
+       struct bch_fs *c = trans->c;
        struct btree_and_journal_iter iter;
        struct bkey_s_c k;
        struct bkey_buf tmp;
@@ -364,11 +365,11 @@ static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b
 
                        btree_and_journal_iter_prefetch(c, b, iter);
 
-                       ret = bch2_btree_and_journal_walk_recurse(c, child,
+                       ret = bch2_btree_and_journal_walk_recurse(trans, child,
                                        btree_id, key_fn);
                        six_unlock_read(&child->c.lock);
                } else {
-                       ret = key_fn(c, k);
+                       ret = key_fn(trans, k);
                }
 
                if (ret)
@@ -382,9 +383,10 @@ static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b
        return ret;
 }
 
-int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
+int bch2_btree_and_journal_walk(struct btree_trans *trans, enum btree_id btree_id,
                                btree_walk_key_fn key_fn)
 {
+       struct bch_fs *c = trans->c;
        struct btree *b = c->btree_roots[btree_id].b;
        int ret = 0;
 
@@ -392,7 +394,7 @@ int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
                return 0;
 
        six_lock_read(&b->c.lock, NULL, NULL);
-       ret = bch2_btree_and_journal_walk_recurse(c, b, btree_id, key_fn);
+       ret = bch2_btree_and_journal_walk_recurse(trans, b, btree_id, key_fn);
        six_unlock_read(&b->c.lock);
 
        return ret;
@@ -516,57 +518,38 @@ static void replay_now_at(struct journal *j, u64 seq)
 }
 
 static int __bch2_journal_replay_key(struct btree_trans *trans,
-                                    enum btree_id id, unsigned level,
-                                    struct bkey_i *k)
+                                    struct journal_key *k)
 {
        struct btree_iter iter;
+       unsigned iter_flags =
+               BTREE_ITER_INTENT|
+               BTREE_ITER_NOT_EXTENTS;
        int ret;
 
-       bch2_trans_node_iter_init(trans, &iter, id, k->k.p,
-                                 BTREE_MAX_DEPTH, level,
-                                 BTREE_ITER_INTENT|
-                                 BTREE_ITER_NOT_EXTENTS);
+       if (!k->level && k->btree_id == BTREE_ID_alloc)
+               iter_flags |= BTREE_ITER_CACHED|BTREE_ITER_CACHED_NOFILL;
+
+       bch2_trans_node_iter_init(trans, &iter, k->btree_id, k->k->k.p,
+                                 BTREE_MAX_DEPTH, k->level,
+                                 iter_flags);
        ret   = bch2_btree_iter_traverse(&iter) ?:
-               bch2_trans_update(trans, &iter, k, BTREE_TRIGGER_NORUN);
+               bch2_trans_update(trans, &iter, k->k, BTREE_TRIGGER_NORUN);
        bch2_trans_iter_exit(trans, &iter);
        return ret;
 }
 
 static int bch2_journal_replay_key(struct bch_fs *c, struct journal_key *k)
 {
-       unsigned commit_flags = BTREE_INSERT_NOFAIL|
-               BTREE_INSERT_LAZY_RW;
+       unsigned commit_flags =
+               BTREE_INSERT_LAZY_RW|
+               BTREE_INSERT_NOFAIL|
+               BTREE_INSERT_JOURNAL_RESERVED;
 
        if (!k->allocated)
                commit_flags |= BTREE_INSERT_JOURNAL_REPLAY;
 
        return bch2_trans_do(c, NULL, NULL, commit_flags,
-                            __bch2_journal_replay_key(&trans, k->btree_id, k->level, k->k));
-}
-
-static int __bch2_alloc_replay_key(struct btree_trans *trans, struct bkey_i *k)
-{
-       struct btree_iter iter;
-       int ret;
-
-       bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc, k->k.p,
-                            BTREE_ITER_CACHED|
-                            BTREE_ITER_CACHED_NOFILL|
-                            BTREE_ITER_INTENT);
-       ret   = bch2_btree_iter_traverse(&iter) ?:
-               bch2_trans_update(trans, &iter, k, BTREE_TRIGGER_NORUN);
-       bch2_trans_iter_exit(trans, &iter);
-       return ret;
-}
-
-static int bch2_alloc_replay_key(struct bch_fs *c, struct bkey_i *k)
-{
-       return bch2_trans_do(c, NULL, NULL,
-                            BTREE_INSERT_NOFAIL|
-                            BTREE_INSERT_USE_RESERVE|
-                            BTREE_INSERT_LAZY_RW|
-                            BTREE_INSERT_JOURNAL_REPLAY,
-                       __bch2_alloc_replay_key(&trans, k));
+                            __bch2_journal_replay_key(&trans, k));
 }
 
 static int journal_sort_seq_cmp(const void *_l, const void *_r)
@@ -604,7 +587,7 @@ static int bch2_journal_replay(struct bch_fs *c,
 
                if (!i->level && i->btree_id == BTREE_ID_alloc) {
                        j->replay_journal_seq = keys.journal_seq_base + i->journal_seq;
-                       ret = bch2_alloc_replay_key(c, i->k);
+                       ret = bch2_journal_replay_key(c, i);
                        if (ret)
                                goto err;
                }
@@ -1004,34 +987,27 @@ static int bch2_fs_upgrade_for_subvolumes(struct btree_trans *trans)
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bch_inode_unpacked inode;
-       struct bkey_inode_buf *packed;
        int ret;
 
        bch2_trans_iter_init(trans, &iter, BTREE_ID_inodes,
-                            POS(0, BCACHEFS_ROOT_INO), 0);
+                            SPOS(0, BCACHEFS_ROOT_INO, U32_MAX), 0);
        k = bch2_btree_iter_peek_slot(&iter);
        ret = bkey_err(k);
        if (ret)
                goto err;
 
-       if (k.k->type != KEY_TYPE_inode) {
+       if (!bkey_is_inode(k.k)) {
                bch_err(c, "root inode not found");
                ret = -ENOENT;
                goto err;
        }
 
-       ret = bch2_inode_unpack(bkey_s_c_to_inode(k), &inode);
+       ret = bch2_inode_unpack(k, &inode);
        BUG_ON(ret);
 
        inode.bi_subvol = BCACHEFS_ROOT_SUBVOL;
 
-       packed = bch2_trans_kmalloc(trans, sizeof(*packed));
-       ret = PTR_ERR_OR_ZERO(packed);
-       if (ret)
-               goto err;
-
-       bch2_inode_pack(c, packed, &inode);
-       ret = bch2_trans_update(trans, &iter, &packed->inode.k_i, 0);
+       ret = bch2_inode_write(trans, &iter, &inode);
 err:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
@@ -1055,6 +1031,8 @@ int bch2_fs_recovery(struct bch_fs *c)
        if (c->sb.clean)
                bch_info(c, "recovering from clean shutdown, journal seq %llu",
                         le64_to_cpu(clean->journal_seq));
+       else
+               bch_info(c, "recovering from unclean shutdown");
 
        if (!(c->sb.features & (1ULL << BCH_FEATURE_new_extent_overwrite))) {
                bch_err(c, "feature new_extent_overwrite not set, filesystem no longer supported");
@@ -1073,7 +1051,6 @@ int bch2_fs_recovery(struct bch_fs *c)
                bch_err(c, "filesystem may have incompatible bkey formats; run fsck from the compat branch to fix");
                ret = -EINVAL;
                goto err;
-
        }
 
        if (!(c->sb.features & (1ULL << BCH_FEATURE_alloc_v2))) {
@@ -1088,17 +1065,20 @@ int bch2_fs_recovery(struct bch_fs *c)
                set_bit(BCH_FS_REBUILD_REPLICAS, &c->flags);
        }
 
-       if (c->sb.version < bcachefs_metadata_version_inode_backpointers) {
-               bch_info(c, "version prior to inode backpointers, upgrade and fsck required");
-               c->opts.version_upgrade = true;
-               c->opts.fsck            = true;
-               c->opts.fix_errors      = FSCK_OPT_YES;
-       } else if (c->sb.version < bcachefs_metadata_version_btree_ptr_sectors_written) {
-               bch_info(c, "version prior to btree_ptr_sectors_written, upgrade required");
-               c->opts.version_upgrade = true;
-       } else if (c->sb.version < bcachefs_metadata_version_snapshot) {
-               bch_info(c, "filesystem version is prior to snapshot field - upgrading");
-               c->opts.version_upgrade = true;
+       if (!c->opts.nochanges) {
+               if (c->sb.version < bcachefs_metadata_version_inode_backpointers) {
+                       bch_info(c, "version prior to inode backpointers, upgrade and fsck required");
+                       c->opts.version_upgrade = true;
+                       c->opts.fsck            = true;
+                       c->opts.fix_errors      = FSCK_OPT_YES;
+               } else if (c->sb.version < bcachefs_metadata_version_subvol_dirent) {
+                       bch_info(c, "filesystem version is prior to subvol_dirent - upgrading");
+                       c->opts.version_upgrade = true;
+                       c->opts.fsck            = true;
+               } else if (c->sb.version < bcachefs_metadata_version_inode_v2) {
+                       bch_info(c, "filesystem version is prior to inode_v2 - upgrading");
+                       c->opts.version_upgrade = true;
+               }
        }
 
        ret = bch2_blacklist_table_initialize(c);
@@ -1258,8 +1238,7 @@ use_clean:
                 */
                bch_verbose(c, "writing allocation info");
                err = "error writing out alloc info";
-               ret = bch2_stripes_write(c, BTREE_INSERT_LAZY_RW) ?:
-                       bch2_alloc_write(c, BTREE_INSERT_LAZY_RW);
+               ret = bch2_alloc_write_all(c, BTREE_INSERT_LAZY_RW);
                if (ret) {
                        bch_err(c, "error writing alloc info");
                        goto err;
@@ -1267,7 +1246,9 @@ use_clean:
                bch_verbose(c, "alloc write done");
        }
 
-       if (c->sb.version < bcachefs_metadata_version_snapshot) {
+       if (c->sb.version < bcachefs_metadata_version_snapshot_2) {
+               bch2_fs_lazy_rw(c);
+
                err = "error creating root snapshot node";
                ret = bch2_fs_initialize_subvolumes(c);
                if (ret)
@@ -1281,7 +1262,7 @@ use_clean:
                goto err;
        bch_verbose(c, "reading snapshots done");
 
-       if (c->sb.version < bcachefs_metadata_version_snapshot) {
+       if (c->sb.version < bcachefs_metadata_version_snapshot_2) {
                /* set bi_subvol on root inode */
                err = "error upgrade root inode for subvolumes";
                ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW,
@@ -1498,7 +1479,7 @@ int bch2_fs_initialize(struct bch_fs *c)
        }
 
        err = "error writing first journal entry";
-       ret = bch2_journal_meta(&c->journal);
+       ret = bch2_journal_flush(&c->journal);
        if (ret)
                goto err;