}
 
 void bch2_btree_node_prefetch(struct bch_fs *c, struct btree_iter *iter,
-                             const struct bkey_i *k, unsigned level)
+                             const struct bkey_i *k,
+                             enum btree_id btree_id, unsigned level)
 {
        struct btree_cache *bc = &c->btree_cache;
        struct btree *b;
 
-       BUG_ON(!btree_node_locked(iter, level + 1));
+       BUG_ON(iter && !btree_node_locked(iter, level + 1));
        BUG_ON(level >= BTREE_MAX_DEPTH);
 
        b = btree_cache_find(bc, k);
        if (b)
                return;
 
-       bch2_btree_node_fill(c, iter, k, iter->btree_id,
-                            level, SIX_LOCK_read, false);
+       bch2_btree_node_fill(c, iter, k, btree_id, level, SIX_LOCK_read, false);
 }
 
 void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
 
                                struct btree *, enum btree_node_sibling);
 
 void bch2_btree_node_prefetch(struct bch_fs *, struct btree_iter *,
-                             const struct bkey_i *, unsigned);
+                             const struct bkey_i *, enum btree_id, unsigned);
 
 void bch2_fs_btree_cache_exit(struct bch_fs *);
 int bch2_fs_btree_cache_init(struct bch_fs *);
 
 
 /* Walk btree, overlaying keys from the journal: */
 
+static void btree_and_journal_iter_prefetch(struct bch_fs *c, struct btree *b,
+                                          struct btree_and_journal_iter iter)
+{
+       unsigned i = 0, nr = b->c.level > 1 ? 2 : 16;
+       struct bkey_s_c k;
+       struct bkey_buf tmp;
+
+       BUG_ON(!b->c.level);
+
+       bch2_bkey_buf_init(&tmp);
+
+       while (i < nr &&
+              (k = bch2_btree_and_journal_iter_peek(&iter)).k) {
+               bch2_bkey_buf_reassemble(&tmp, c, k);
+
+               bch2_btree_node_prefetch(c, NULL, tmp.k,
+                                       b->c.btree_id, b->c.level - 1);
+
+               bch2_btree_and_journal_iter_advance(&iter);
+               i++;
+       }
+
+       bch2_bkey_buf_exit(&tmp, c);
+}
+
 static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b,
                                struct journal_keys *journal_keys,
                                enum btree_id btree_id,
 {
        struct btree_and_journal_iter iter;
        struct bkey_s_c k;
+       struct bkey_buf tmp;
+       struct btree *child;
        int ret = 0;
 
+       bch2_bkey_buf_init(&tmp);
        bch2_btree_and_journal_iter_init_node_iter(&iter, journal_keys, b);
 
        while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
                        break;
 
                if (b->c.level) {
-                       struct btree *child;
-                       struct bkey_buf tmp;
-
-                       bch2_bkey_buf_init(&tmp);
                        bch2_bkey_buf_reassemble(&tmp, c, k);
-                       k = bkey_i_to_s_c(tmp.k);
 
                        bch2_btree_and_journal_iter_advance(&iter);
 
                        child = bch2_btree_node_get_noiter(c, tmp.k,
                                                b->c.btree_id, b->c.level - 1);
-                       bch2_bkey_buf_exit(&tmp, c);
 
                        ret = PTR_ERR_OR_ZERO(child);
                        if (ret)
                                break;
 
+                       btree_and_journal_iter_prefetch(c, b, iter);
+
                        ret   = (node_fn ? node_fn(c, b) : 0) ?:
                                bch2_btree_and_journal_walk_recurse(c, child,
                                        journal_keys, btree_id, node_fn, key_fn);
                }
        }
 
+       bch2_bkey_buf_exit(&tmp, c);
        return ret;
 }