bch2_trans_update(trans, iter, &a->k_i,
                          BTREE_TRIGGER_NORUN);
        ret = bch2_trans_commit(trans, NULL, NULL,
-                               BTREE_INSERT_NOFAIL|flags);
+                               BTREE_INSERT_NOFAIL|
+                               BTREE_INSERT_USE_RESERVE|
+                               flags);
 err:
        if (ret == -EINTR)
                goto retry;
                set_current_state(TASK_INTERRUPTIBLE);
 
                spin_lock(&c->freelist_lock);
-               for (i = 0; i < RESERVE_NR; i++)
+               for (i = 0; i < RESERVE_NR; i++) {
+
+                       /*
+                        * Don't strand buckets on the copygc freelist until
+                        * after recovery is finished:
+                        */
+                       if (!test_bit(BCH_FS_STARTED, &c->flags) &&
+                           i == RESERVE_MOVINGGC)
+                               continue;
+
                        if (fifo_push(&ca->free[i], bucket)) {
                                fifo_pop(&ca->free_inc, bucket);
 
                                spin_unlock(&c->freelist_lock);
                                goto out;
                        }
+               }
 
                if (ca->allocator_state != ALLOCATOR_BLOCKED_FULL) {
                        ca->allocator_state = ALLOCATOR_BLOCKED_FULL;
 
        if (bch2_fs_init_fault("fs_start"))
                goto err;
 
+       set_bit(BCH_FS_STARTED, &c->flags);
+
        if (c->opts.read_only || c->opts.nochanges) {
                bch2_fs_read_only(c);
        } else {
                        goto err;
        }
 
-       set_bit(BCH_FS_STARTED, &c->flags);
        print_mount_opts(c);
        ret = 0;
 out: