return inum;
 }
 
-int bch2_empty_dir(struct bch_fs *c, u64 dir_inum)
+int bch2_empty_dir_trans(struct btree_trans *trans, u64 dir_inum)
 {
-       struct btree_trans trans;
        struct btree_iter *iter;
        struct bkey_s_c k;
        int ret = 0;
 
-       bch2_trans_init(&trans, c);
+       iter = bch2_trans_get_iter(trans, BTREE_ID_DIRENTS,
+                                  POS(dir_inum, 0), 0);
+       if (IS_ERR(iter))
+               return PTR_ERR(iter);
 
-       for_each_btree_key(&trans, iter, BTREE_ID_DIRENTS,
-                          POS(dir_inum, 0), 0, k) {
+       for_each_btree_key_continue(iter, 0, k) {
                if (k.k->p.inode > dir_inum)
                        break;
 
                        break;
                }
        }
-       bch2_trans_exit(&trans);
+       bch2_trans_iter_put(trans, iter);
 
        return ret;
 }
 
+int bch2_empty_dir(struct bch_fs *c, u64 dir_inum)
+{
+       return bch2_trans_do(c, NULL, 0,
+               bch2_empty_dir_trans(&trans, dir_inum));
+}
+
 int bch2_readdir(struct bch_fs *c, struct file *file,
                 struct dir_context *ctx)
 {
 
        };
 }
 
-static int walk_inode(struct bch_fs *c, struct inode_walker *w, u64 inum)
+static int walk_inode(struct btree_trans *trans,
+                     struct inode_walker *w, u64 inum)
 {
-       w->first_this_inode     = inum != w->cur_inum;
-       w->cur_inum             = inum;
-
-       if (w->first_this_inode) {
-               int ret = bch2_inode_find_by_inum(c, inum, &w->inode);
+       if (inum != w->cur_inum) {
+               int ret = bch2_inode_find_by_inum_trans(trans, inum,
+                                                       &w->inode);
 
                if (ret && ret != -ENOENT)
                        return ret;
 
-               w->have_inode = !ret;
+               w->have_inode   = !ret;
+               w->cur_inum     = inum;
+               w->first_this_inode = true;
+       } else {
+               w->first_this_inode = false;
        }
 
        return 0;
        int ret = 0;
 
        bch2_trans_init(&trans, c);
+       bch2_trans_preload_iters(&trans);
 
        bch_verbose(c, "checking extents");
 
-       for_each_btree_key(&trans, iter, BTREE_ID_EXTENTS,
-                          POS(BCACHEFS_ROOT_INO, 0), 0, k) {
-               ret = walk_inode(c, &w, k.k->p.inode);
+       iter = bch2_trans_get_iter(&trans, BTREE_ID_EXTENTS,
+                                  POS(BCACHEFS_ROOT_INO, 0), 0);
+retry:
+       for_each_btree_key_continue(iter, 0, k) {
+               ret = walk_inode(&trans, &w, k.k->p.inode);
                if (ret)
                        break;
 
        }
 err:
 fsck_err:
+       if (ret == -EINTR)
+               goto retry;
        return bch2_trans_exit(&trans) ?: ret;
 }
 
        bch_verbose(c, "checking dirents");
 
        bch2_trans_init(&trans, c);
-
        bch2_trans_preload_iters(&trans);
 
-       iter = bch2_trans_get_iter(&trans, BTREE_ID_DIRENTS,
-                                  POS(BCACHEFS_ROOT_INO, 0), 0);
-
        hash_check_init(&h);
 
+       iter = bch2_trans_get_iter(&trans, BTREE_ID_DIRENTS,
+                                  POS(BCACHEFS_ROOT_INO, 0), 0);
+retry:
        for_each_btree_key_continue(iter, 0, k) {
                struct bkey_s_c_dirent d;
                struct bch_inode_unpacked target;
                bool have_target;
                u64 d_inum;
 
-               ret = walk_inode(c, &w, k.k->p.inode);
+               ret = walk_inode(&trans, &w, k.k->p.inode);
                if (ret)
                        break;
 
                        continue;
                }
 
-               ret = bch2_inode_find_by_inum(c, d_inum, &target);
+               ret = bch2_inode_find_by_inum_trans(&trans, d_inum, &target);
                if (ret && ret != -ENOENT)
                        break;
 
        hash_stop_chain(&trans, &h);
 err:
 fsck_err:
+       if (ret == -EINTR)
+               goto retry;
+
        return bch2_trans_exit(&trans) ?: ret;
 }
 
 
        bch_verbose(c, "checking xattrs");
 
-       bch2_trans_init(&trans, c);
+       hash_check_init(&h);
 
+       bch2_trans_init(&trans, c);
        bch2_trans_preload_iters(&trans);
 
        iter = bch2_trans_get_iter(&trans, BTREE_ID_XATTRS,
                                   POS(BCACHEFS_ROOT_INO, 0), 0);
-
-       hash_check_init(&h);
-
+retry:
        for_each_btree_key_continue(iter, 0, k) {
-               ret = walk_inode(c, &w, k.k->p.inode);
+               ret = walk_inode(&trans, &w, k.k->p.inode);
                if (ret)
                        break;
 
        }
 err:
 fsck_err:
+       if (ret == -EINTR)
+               goto retry;
        return bch2_trans_exit(&trans) ?: ret;
 }
 
        int ret = 0;
 
        bch2_trans_init(&trans, c);
+       bch2_trans_preload_iters(&trans);
 
        bch_verbose(c, "checking directory structure");
 
        }
 
        ret = path_down(&path, BCACHEFS_ROOT_INO);
-       if (ret) {
-               return ret;
-       }
+       if (ret)
+               goto err;
 
        while (path.nr) {
 next:
                path.nr--;
        }
 
-       for_each_btree_key(&trans, iter, BTREE_ID_INODES, POS_MIN, 0, k) {
+       iter = bch2_trans_get_iter(&trans, BTREE_ID_INODES, POS_MIN, 0);
+retry:
+       for_each_btree_key_continue(iter, 0, k) {
                if (k.k->type != KEY_TYPE_inode)
                        continue;
 
                if (!S_ISDIR(le16_to_cpu(bkey_s_c_to_inode(k).v->bi_mode)))
                        continue;
 
-               if (!bch2_empty_dir(c, k.k->p.inode))
+               ret = bch2_empty_dir_trans(&trans, k.k->p.inode);
+               if (ret == -EINTR)
+                       goto retry;
+               if (!ret)
                        continue;
 
                if (fsck_err_on(!inode_bitmap_test(&dirs_done, k.k->p.inode), c,
                memset(&path, 0, sizeof(path));
                goto restart_dfs;
        }
-
-out:
-       kfree(dirs_done.bits);
-       kfree(path.entries);
-       return ret;
 err:
 fsck_err:
        ret = bch2_trans_exit(&trans) ?: ret;
-       goto out;
+       kfree(dirs_done.bits);
+       kfree(path.entries);
+       return ret;
 }
 
 struct nlink {
        int ret;
 
        bch2_trans_init(&trans, c);
+       bch2_trans_preload_iters(&trans);
 
        inc_link(c, links, range_start, range_end, BCACHEFS_ROOT_INO, false);
 
        u64 nlinks_pos;
 
        bch2_trans_init(&trans, c);
+       bch2_trans_preload_iters(&trans);
 
        iter = bch2_trans_get_iter(&trans, BTREE_ID_INODES,
                                   POS(range_start, 0), 0);
        int ret = 0, ret2;
 
        bch2_trans_init(&trans, c);
+       bch2_trans_preload_iters(&trans);
 
        iter = bch2_trans_get_iter(&trans, BTREE_ID_INODES,
                                   POS_MIN, 0);
 
        return ret;
 }
 
-int bch2_inode_find_by_inum(struct bch_fs *c, u64 inode_nr,
-                           struct bch_inode_unpacked *inode)
+int bch2_inode_find_by_inum_trans(struct btree_trans *trans, u64 inode_nr,
+                                 struct bch_inode_unpacked *inode)
 {
-       struct btree_trans trans;
        struct btree_iter *iter;
        struct bkey_s_c k;
        int ret = -ENOENT;
 
-       bch2_trans_init(&trans, c);
+       iter = bch2_trans_get_iter(trans, BTREE_ID_INODES,
+                       POS(inode_nr, 0), BTREE_ITER_SLOTS);
+       if (IS_ERR(iter))
+               return PTR_ERR(iter);
 
-       for_each_btree_key(&trans, iter, BTREE_ID_INODES,
-                          POS(inode_nr, 0), BTREE_ITER_SLOTS, k) {
-               switch (k.k->type) {
-               case KEY_TYPE_inode:
-                       ret = bch2_inode_unpack(bkey_s_c_to_inode(k), inode);
-                       break;
-               default:
-                       /* hole, not found */
-                       break;
-               }
+       k = bch2_btree_iter_peek_slot(iter);
+       if (k.k->type == KEY_TYPE_inode)
+               ret = bch2_inode_unpack(bkey_s_c_to_inode(k), inode);
 
-               break;
-       }
+       bch2_trans_iter_put(trans, iter);
 
-       return bch2_trans_exit(&trans) ?: ret;
+       return ret;
+}
+
+int bch2_inode_find_by_inum(struct bch_fs *c, u64 inode_nr,
+                           struct bch_inode_unpacked *inode)
+{
+       return bch2_trans_do(c, NULL, 0,
+               bch2_inode_find_by_inum_trans(&trans, inode_nr, inode));
 }
 
 #ifdef CONFIG_BCACHEFS_DEBUG