- struct bch_fs *c = ca->fs;
- struct bucket *g;
- struct bucket_mark new;
- u64 sectors_to_move;
- size_t buckets_to_move, buckets_unused = 0;
- struct bucket_heap_entry e;
- unsigned sectors_used, i;
- int reserve_sectors;
-
- if (!have_copygc_reserve(ca)) {
- struct closure cl;
-
- closure_init_stack(&cl);
- while (1) {
- closure_wait(&c->freelist_wait, &cl);
- if (have_copygc_reserve(ca))
- break;
- closure_sync(&cl);
- }
- closure_wake_up(&c->freelist_wait);
+ struct bch_move_stats move_stats;
+ struct btree_trans trans;
+ struct moving_context ctxt;
+ struct data_update_opts data_opts = {
+ .btree_insert_flags = BTREE_INSERT_USE_RESERVE|JOURNAL_WATERMARK_copygc,
+ };
+ struct bpos bucket;
+ struct bpos pos;
+ u8 gen = 0;
+ unsigned nr_evacuated;
+ int ret = 0;
+
+ bch2_move_stats_init(&move_stats, "copygc");
+ bch2_moving_ctxt_init(&ctxt, c, NULL, &move_stats,
+ writepoint_ptr(&c->copygc_write_point),
+ false);
+ bch2_trans_init(&trans, c, 0, 0);
+
+ ret = bch2_btree_write_buffer_flush(&trans);
+ BUG_ON(ret);
+
+ for (nr_evacuated = 0, pos = POS_MIN;
+ nr_evacuated < 32 && !ret;
+ nr_evacuated++, pos = bpos_nosnap_successor(pos)) {
+ ret = bch2_copygc_next_bucket(&trans, &bucket, &gen, &pos) ?:
+ __bch2_evacuate_bucket(&trans, &ctxt, bucket, gen, data_opts);
+ if (bkey_eq(pos, POS_MAX))
+ break;