bch2_trans_update(trans, iter, &a->k_i,
                          BTREE_TRIGGER_NORUN);
        ret = bch2_trans_commit(trans, NULL, NULL,
-                               BTREE_INSERT_NOFAIL|
-                               BTREE_INSERT_USE_RESERVE|
-                               flags);
+                               BTREE_INSERT_NOFAIL|flags);
 err:
        if (ret == -EINTR)
                goto retry;
 
                if (available > fifo_free(&ca->free_inc) ||
                    (available &&
-                    (!fifo_full(&ca->free[RESERVE_BTREE]) ||
-                     !fifo_full(&ca->free[RESERVE_MOVINGGC]))))
+                    !fifo_full(&ca->free[RESERVE_MOVINGGC])))
                        break;
 
                up_read(&c->gc_lock);
                                BTREE_INSERT_NOUNLOCK|
                                BTREE_INSERT_NOCHECK_RW|
                                BTREE_INSERT_NOFAIL|
-                               BTREE_INSERT_USE_RESERVE|
-                               BTREE_INSERT_USE_ALLOC_RESERVE|
+                               BTREE_INSERT_JOURNAL_RESERVED|
                                flags);
        if (ret == -EINTR)
                goto retry;
 
 static inline unsigned open_buckets_reserved(enum alloc_reserve reserve)
 {
        switch (reserve) {
-       case RESERVE_ALLOC:
+       case RESERVE_MOVINGGC:
                return 0;
-       case RESERVE_BTREE:
-               return OPEN_BUCKETS_COUNT / 4;
        default:
                return OPEN_BUCKETS_COUNT / 2;
        }
                goto out;
 
        switch (reserve) {
-       case RESERVE_ALLOC:
-               if (fifo_pop(&ca->free[RESERVE_BTREE], bucket))
-                       goto out;
-               break;
-       case RESERVE_BTREE:
-               if (fifo_used(&ca->free[RESERVE_BTREE]) * 2 >=
-                   ca->free[RESERVE_BTREE].size &&
-                   fifo_pop(&ca->free[RESERVE_BTREE], bucket))
-                       goto out;
-               break;
        case RESERVE_MOVINGGC:
                if (fifo_pop(&ca->free[RESERVE_MOVINGGC], bucket))
                        goto out;
 
 /* There is one reserve for each type of btree, one for prios and gens
  * and one for moving GC */
 enum alloc_reserve {
-       RESERVE_ALLOC           = -1,
-       RESERVE_BTREE           = 0,
-       RESERVE_MOVINGGC        = 1,
-       RESERVE_NONE            = 2,
-       RESERVE_NR              = 3,
+       RESERVE_MOVINGGC        = 0,
+       RESERVE_NONE            = 1,
+       RESERVE_NR              = 2,
 };
 
 typedef FIFO(long)     alloc_fifo;
 
                        if (max_stale > 64)
                                bch2_btree_node_rewrite(c, iter,
                                                b->data->keys.seq,
-                                               BTREE_INSERT_USE_RESERVE|
                                                BTREE_INSERT_NOWAIT|
                                                BTREE_INSERT_GC_LOCK_HELD);
                        else if (!bch2_btree_gc_rewrite_disabled &&
 
                                  BTREE_INSERT_NOUNLOCK|
                                  BTREE_INSERT_NOCHECK_RW|
                                  BTREE_INSERT_NOFAIL|
-                                 BTREE_INSERT_USE_RESERVE|
-                                 BTREE_INSERT_USE_ALLOC_RESERVE|
                                  BTREE_INSERT_JOURNAL_RESERVED|
                                  BTREE_INSERT_JOURNAL_RECLAIM);
 err:
 
        __BTREE_INSERT_NOCHECK_RW,
        __BTREE_INSERT_LAZY_RW,
        __BTREE_INSERT_USE_RESERVE,
-       __BTREE_INSERT_USE_ALLOC_RESERVE,
        __BTREE_INSERT_JOURNAL_REPLAY,
        __BTREE_INSERT_JOURNAL_RESERVED,
        __BTREE_INSERT_JOURNAL_RECLAIM,
 
 /* for copygc, or when merging btree nodes */
 #define BTREE_INSERT_USE_RESERVE       (1 << __BTREE_INSERT_USE_RESERVE)
-#define BTREE_INSERT_USE_ALLOC_RESERVE (1 << __BTREE_INSERT_USE_ALLOC_RESERVE)
 
 /* Insert is for journal replay - don't get journal reservations: */
 #define BTREE_INSERT_JOURNAL_REPLAY    (1 << __BTREE_INSERT_JOURNAL_REPLAY)
 
        unsigned nr_reserve;
        enum alloc_reserve alloc_reserve;
 
-       if (flags & BTREE_INSERT_USE_ALLOC_RESERVE) {
+       if (flags & BTREE_INSERT_USE_RESERVE) {
                nr_reserve      = 0;
-               alloc_reserve   = RESERVE_ALLOC;
-       } else if (flags & BTREE_INSERT_USE_RESERVE) {
-               nr_reserve      = BTREE_NODE_RESERVE / 2;
-               alloc_reserve   = RESERVE_BTREE;
+               alloc_reserve   = RESERVE_MOVINGGC;
        } else {
                nr_reserve      = BTREE_NODE_RESERVE;
                alloc_reserve   = RESERVE_NONE;
        bch2_trans_init(&trans, c, 0, 512);
        ret = __bch2_trans_do(&trans, &as->disk_res, &journal_seq,
                              BTREE_INSERT_NOFAIL|
-                             BTREE_INSERT_USE_RESERVE|
-                             BTREE_INSERT_USE_ALLOC_RESERVE|
                              BTREE_INSERT_NOCHECK_RW|
                              BTREE_INSERT_JOURNAL_RECLAIM|
                              BTREE_INSERT_JOURNAL_RESERVED,
        struct btree_update *as;
        struct closure cl;
        int ret = 0;
-       struct btree_insert_entry *i;
-
-       /*
-        * We already have a disk reservation and open buckets pinned; this
-        * allocation must not block:
-        */
-       trans_for_each_update(trans, i)
-               if (btree_node_type_needs_gc(i->iter->btree_id))
-                       flags |= BTREE_INSERT_USE_RESERVE;
 
        closure_init_stack(&cl);
 
 retry:
        as = bch2_btree_update_start(iter->trans, iter->btree_id,
                parent ? btree_update_reserve_required(c, parent) : 0,
-               BTREE_INSERT_NOFAIL|
-               BTREE_INSERT_USE_RESERVE|
-               BTREE_INSERT_USE_ALLOC_RESERVE,
-               &cl);
+               BTREE_INSERT_NOFAIL, &cl);
 
        if (IS_ERR(as)) {
                ret = PTR_ERR(as);
 
 
        bch2_trans_update(trans, iter, &k, 0);
        return bch2_trans_commit(trans, NULL, NULL,
-                                BTREE_INSERT_NOFAIL|
-                                BTREE_INSERT_USE_RESERVE|flags);
+                                BTREE_INSERT_NOFAIL|flags);
 }
 
 int bch2_btree_delete_range_trans(struct btree_trans *trans, enum btree_id id,
 
                             ca->mi.bucket_size / c->opts.btree_node_size);
        /* XXX: these should be tunable */
        size_t reserve_none     = max_t(size_t, 1, nbuckets >> 9);
-       size_t copygc_reserve   = max_t(size_t, 2, nbuckets >> 7);
+       size_t copygc_reserve   = max_t(size_t, 2, nbuckets >> 6);
        size_t free_inc_nr      = max(max_t(size_t, 1, nbuckets >> 12),
                                      btree_reserve * 2);
        bool resize = ca->buckets[0] != NULL;
            !(buckets_nouse     = kvpmalloc(BITS_TO_LONGS(nbuckets) *
                                            sizeof(unsigned long),
                                            GFP_KERNEL|__GFP_ZERO)) ||
-           !init_fifo(&free[RESERVE_BTREE], btree_reserve, GFP_KERNEL) ||
            !init_fifo(&free[RESERVE_MOVINGGC],
                       copygc_reserve, GFP_KERNEL) ||
            !init_fifo(&free[RESERVE_NONE], reserve_none, GFP_KERNEL) ||
 
                bch2_trans_update(&trans, iter, sk.k, 0);
 
                ret = bch2_trans_commit(&trans, NULL, NULL,
-                                       BTREE_INSERT_NOFAIL|
-                                       BTREE_INSERT_USE_RESERVE);
+                                       BTREE_INSERT_NOFAIL);
                if (ret == -EINTR)
                        ret = 0;
                if (ret)
 
 
        ret = bch2_trans_commit(trans, disk_res, journal_seq,
                                BTREE_INSERT_NOCHECK_RW|
-                               BTREE_INSERT_NOFAIL|
-                               BTREE_INSERT_USE_RESERVE);
+                               BTREE_INSERT_NOFAIL);
        if (ret)
                return ret;
 
 
                        }
                } else {
                        rcu_read_lock();
-                       ob = bch2_bucket_alloc(c, ca, RESERVE_ALLOC,
+                       ob = bch2_bucket_alloc(c, ca, RESERVE_NONE,
                                               false, cl);
                        rcu_read_unlock();
                        if (IS_ERR(ob)) {
 
                ret = bch2_trans_commit(&trans, &op->res,
                                op_journal_seq(op),
                                BTREE_INSERT_NOFAIL|
-                               BTREE_INSERT_USE_RESERVE|
                                m->data_opts.btree_insert_flags);
                if (!ret)
                        atomic_long_inc(&c->extent_migrate_done);
 
                return -1;
        }
 
+       /*
+        * Our btree node allocations also come out of RESERVE_MOVINGGC:
+        */
+       sectors_to_move = (sectors_to_move * 3) / 4;
+
        for (i = h->data; i < h->data + h->used; i++)
                sectors_to_move += i->sectors * i->replicas;
 
 
 
        pr_buf(out,
                "free_inc:               %zu/%zu\n"
-               "free[RESERVE_BTREE]:    %zu/%zu\n"
                "free[RESERVE_MOVINGGC]: %zu/%zu\n"
                "free[RESERVE_NONE]:     %zu/%zu\n"
                "buckets:\n"
                "open_buckets_user:      %u\n"
                "btree reserve cache:    %u\n",
                fifo_used(&ca->free_inc),               ca->free_inc.size,
-               fifo_used(&ca->free[RESERVE_BTREE]),    ca->free[RESERVE_BTREE].size,
                fifo_used(&ca->free[RESERVE_MOVINGGC]), ca->free[RESERVE_MOVINGGC].size,
                fifo_used(&ca->free[RESERVE_NONE]),     ca->free[RESERVE_NONE].size,
                ca->mi.nbuckets - ca->mi.first_bucket,