get_alloc_field(a.v, &d, i));
 }
 
-static inline struct bkey_alloc_unpacked
-alloc_mem_to_key(struct bucket *g, struct bucket_mark m)
-{
-       return (struct bkey_alloc_unpacked) {
-               .gen            = m.gen,
-               .oldest_gen     = g->oldest_gen,
-               .data_type      = m.data_type,
-               .dirty_sectors  = m.dirty_sectors,
-               .cached_sectors = m.cached_sectors,
-               .read_time      = g->io_time[READ],
-               .write_time     = g->io_time[WRITE],
-       };
-}
-
 int bch2_alloc_read(struct bch_fs *c, struct journal_keys *journal_keys)
 {
        struct btree_trans trans;
 
 void bch2_alloc_pack(struct bkey_i_alloc *,
                     const struct bkey_alloc_unpacked);
 
+static inline struct bkey_alloc_unpacked
+alloc_mem_to_key(struct bucket *g, struct bucket_mark m)
+{
+       return (struct bkey_alloc_unpacked) {
+               .gen            = m.gen,
+               .oldest_gen     = g->oldest_gen,
+               .data_type      = m.data_type,
+               .dirty_sectors  = m.dirty_sectors,
+               .cached_sectors = m.cached_sectors,
+               .read_time      = g->io_time[READ],
+               .write_time     = g->io_time[WRITE],
+       };
+}
+
 #define ALLOC_SCAN_BATCH(ca)           max_t(size_t, 1, (ca)->mi.nbuckets >> 9)
 
 const char *bch2_alloc_invalid(const struct bch_fs *, struct bkey_s_c);
 
                     : !bkey_cmp(pos, i->iter->pos))) {
                        *iter   = i->iter;
                        *k      = bkey_i_to_s_c(i->k);
-                       return 0;
+                       return 1;
                }
 
        *iter = __bch2_trans_get_iter(trans, btree_id, pos,
        ret = trans_get_key(trans, BTREE_ID_ALLOC,
                            POS(p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr)),
                            &iter, &k);
-       if (ret)
+       if (ret < 0)
                return ret;
 
-       if (k.k->type != KEY_TYPE_alloc) {
-               bch_err_ratelimited(c, "pointer to nonexistent bucket %u:%zu",
-                                   p.ptr.dev,
-                                   PTR_BUCKET_NR(ca, &p.ptr));
-               ret = -1;
-               goto out;
-       }
+       if (!ret) {
+               /*
+                * During journal replay, and if gc repairs alloc info at
+                * runtime, the alloc info in the btree might not be up to date
+                * yet - so, trust the in memory mark:
+                */
+               struct bucket *g;
+               struct bucket_mark m;
 
-       u = bch2_alloc_unpack(k);
+               percpu_down_read(&c->mark_lock);
+               g       = bucket(ca, iter->pos.offset);
+               m       = READ_ONCE(g->mark);
+               u       = alloc_mem_to_key(g, m);
+               percpu_up_read(&c->mark_lock);
+       } else {
+               /*
+                * Unless we're already updating that key:
+                */
+               if (k.k->type != KEY_TYPE_alloc) {
+                       bch_err_ratelimited(c, "pointer to nonexistent bucket %u:%zu",
+                                           p.ptr.dev,
+                                           PTR_BUCKET_NR(ca, &p.ptr));
+                       ret = -1;
+                       goto out;
+               }
+
+               u = bch2_alloc_unpack(k);
+       }
 
        if (gen_after(u.gen, p.ptr.gen)) {
                ret = 1;
        int ret = 0;
 
        ret = trans_get_key(trans, BTREE_ID_EC, POS(0, p.idx), &iter, &k);
-       if (ret)
+       if (ret < 0)
                return ret;
 
        if (k.k->type != KEY_TYPE_stripe) {
 
        ret = trans_get_key(trans, BTREE_ID_REFLINK,
                            POS(0, idx), &iter, &k);
-       if (ret)
+       if (ret < 0)
                return ret;
 
        if (k.k->type != KEY_TYPE_reflink_v) {