+ bch2_journal_iter_init(c, &iter->journal,
+ b->c.btree_id, b->c.level, b->data->min_key);
+}
+
+/* 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,
+ enum btree_id btree_id,
+ btree_walk_key_fn key_fn)
+{
+ 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, c, b);
+
+ while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
+ if (b->c.level) {
+ bch2_bkey_buf_reassemble(&tmp, c, k);
+
+ child = bch2_btree_node_get_noiter(c, tmp.k,
+ b->c.btree_id, b->c.level - 1,
+ false);
+
+ ret = PTR_ERR_OR_ZERO(child);
+ if (ret)
+ break;
+
+ btree_and_journal_iter_prefetch(c, b, iter);
+
+ ret = bch2_btree_and_journal_walk_recurse(c, child,
+ btree_id, key_fn);
+ six_unlock_read(&child->c.lock);
+ } else {
+ ret = key_fn(c, k);
+ }
+
+ if (ret)
+ break;
+
+ bch2_btree_and_journal_iter_advance(&iter);
+ }
+
+ bch2_btree_and_journal_iter_exit(&iter);
+ bch2_bkey_buf_exit(&tmp, c);
+ return ret;
+}
+
+int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
+ btree_walk_key_fn key_fn)
+{
+ struct btree *b = c->btree_roots[btree_id].b;
+ int ret = 0;
+
+ if (btree_node_fake(b))
+ return 0;
+
+ six_lock_read(&b->c.lock, NULL, NULL);
+ ret = bch2_btree_and_journal_walk_recurse(c, b, btree_id, key_fn);
+ six_unlock_read(&b->c.lock);
+
+ return ret;