Commit 63316903 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: moving_context now owns a btree_trans

btree_trans and moving_context are used together, and having the
moving_context owns the transaction object reduces some plumbing.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent a0bfe3b0
...@@ -487,7 +487,7 @@ int bch2_data_update_init(struct btree_trans *trans, ...@@ -487,7 +487,7 @@ int bch2_data_update_init(struct btree_trans *trans,
if (c->opts.nocow_enabled) { if (c->opts.nocow_enabled) {
if (ctxt) { if (ctxt) {
move_ctxt_wait_event(ctxt, trans, move_ctxt_wait_event(ctxt,
(locked = bch2_bucket_nocow_trylock(&c->nocow_locks, (locked = bch2_bucket_nocow_trylock(&c->nocow_locks,
PTR_BUCKET_POS(c, &p.ptr), 0)) || PTR_BUCKET_POS(c, &p.ptr), 0)) ||
!atomic_read(&ctxt->read_sectors)); !atomic_read(&ctxt->read_sectors));
......
...@@ -157,13 +157,11 @@ static void move_read_endio(struct bio *bio) ...@@ -157,13 +157,11 @@ static void move_read_endio(struct bio *bio)
closure_put(&ctxt->cl); closure_put(&ctxt->cl);
} }
void bch2_moving_ctxt_do_pending_writes(struct moving_context *ctxt, void bch2_moving_ctxt_do_pending_writes(struct moving_context *ctxt)
struct btree_trans *trans)
{ {
struct moving_io *io; struct moving_io *io;
if (trans) bch2_trans_unlock(ctxt->trans);
bch2_trans_unlock(trans);
while ((io = bch2_moving_ctxt_next_pending_write(ctxt))) { while ((io = bch2_moving_ctxt_next_pending_write(ctxt))) {
list_del(&io->read_list); list_del(&io->read_list);
...@@ -171,21 +169,20 @@ void bch2_moving_ctxt_do_pending_writes(struct moving_context *ctxt, ...@@ -171,21 +169,20 @@ void bch2_moving_ctxt_do_pending_writes(struct moving_context *ctxt,
} }
} }
void bch2_move_ctxt_wait_for_io(struct moving_context *ctxt, void bch2_move_ctxt_wait_for_io(struct moving_context *ctxt)
struct btree_trans *trans)
{ {
unsigned sectors_pending = atomic_read(&ctxt->write_sectors); unsigned sectors_pending = atomic_read(&ctxt->write_sectors);
move_ctxt_wait_event(ctxt, trans, move_ctxt_wait_event(ctxt,
!atomic_read(&ctxt->write_sectors) || !atomic_read(&ctxt->write_sectors) ||
atomic_read(&ctxt->write_sectors) != sectors_pending); atomic_read(&ctxt->write_sectors) != sectors_pending);
} }
void bch2_moving_ctxt_exit(struct moving_context *ctxt) void bch2_moving_ctxt_exit(struct moving_context *ctxt)
{ {
struct bch_fs *c = ctxt->c; struct bch_fs *c = ctxt->trans->c;
move_ctxt_wait_event(ctxt, NULL, list_empty(&ctxt->reads)); move_ctxt_wait_event(ctxt, list_empty(&ctxt->reads));
closure_sync(&ctxt->cl); closure_sync(&ctxt->cl);
EBUG_ON(atomic_read(&ctxt->write_sectors)); EBUG_ON(atomic_read(&ctxt->write_sectors));
...@@ -203,6 +200,9 @@ void bch2_moving_ctxt_exit(struct moving_context *ctxt) ...@@ -203,6 +200,9 @@ void bch2_moving_ctxt_exit(struct moving_context *ctxt)
mutex_lock(&c->moving_context_lock); mutex_lock(&c->moving_context_lock);
list_del(&ctxt->list); list_del(&ctxt->list);
mutex_unlock(&c->moving_context_lock); mutex_unlock(&c->moving_context_lock);
bch2_trans_put(ctxt->trans);
memset(ctxt, 0, sizeof(*ctxt));
} }
void bch2_moving_ctxt_init(struct moving_context *ctxt, void bch2_moving_ctxt_init(struct moving_context *ctxt,
...@@ -214,7 +214,7 @@ void bch2_moving_ctxt_init(struct moving_context *ctxt, ...@@ -214,7 +214,7 @@ void bch2_moving_ctxt_init(struct moving_context *ctxt,
{ {
memset(ctxt, 0, sizeof(*ctxt)); memset(ctxt, 0, sizeof(*ctxt));
ctxt->c = c; ctxt->trans = bch2_trans_get(c);
ctxt->fn = (void *) _RET_IP_; ctxt->fn = (void *) _RET_IP_;
ctxt->rate = rate; ctxt->rate = rate;
ctxt->stats = stats; ctxt->stats = stats;
...@@ -287,14 +287,14 @@ static int bch2_extent_drop_ptrs(struct btree_trans *trans, ...@@ -287,14 +287,14 @@ static int bch2_extent_drop_ptrs(struct btree_trans *trans,
bch2_trans_commit(trans, NULL, NULL, BTREE_INSERT_NOFAIL); bch2_trans_commit(trans, NULL, NULL, BTREE_INSERT_NOFAIL);
} }
int bch2_move_extent(struct btree_trans *trans, int bch2_move_extent(struct moving_context *ctxt,
struct btree_iter *iter,
struct moving_context *ctxt,
struct move_bucket_in_flight *bucket_in_flight, struct move_bucket_in_flight *bucket_in_flight,
struct bch_io_opts io_opts, struct btree_iter *iter,
struct bkey_s_c k, struct bkey_s_c k,
struct bch_io_opts io_opts,
struct data_update_opts data_opts) struct data_update_opts data_opts)
{ {
struct btree_trans *trans = ctxt->trans;
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
struct moving_io *io; struct moving_io *io;
...@@ -499,14 +499,13 @@ int bch2_move_get_io_opts_one(struct btree_trans *trans, ...@@ -499,14 +499,13 @@ int bch2_move_get_io_opts_one(struct btree_trans *trans,
return 0; return 0;
} }
int bch2_move_ratelimit(struct btree_trans *trans, int bch2_move_ratelimit(struct moving_context *ctxt)
struct moving_context *ctxt)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = ctxt->trans->c;
u64 delay; u64 delay;
if (ctxt->wait_on_copygc) { if (ctxt->wait_on_copygc) {
bch2_trans_unlock(trans); bch2_trans_unlock(ctxt->trans);
wait_event_killable(c->copygc_running_wq, wait_event_killable(c->copygc_running_wq,
!c->copygc_running || !c->copygc_running ||
kthread_should_stop()); kthread_should_stop());
...@@ -516,7 +515,7 @@ int bch2_move_ratelimit(struct btree_trans *trans, ...@@ -516,7 +515,7 @@ int bch2_move_ratelimit(struct btree_trans *trans,
delay = ctxt->rate ? bch2_ratelimit_delay(ctxt->rate) : 0; delay = ctxt->rate ? bch2_ratelimit_delay(ctxt->rate) : 0;
if (delay) { if (delay) {
bch2_trans_unlock(trans); bch2_trans_unlock(ctxt->trans);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
} }
...@@ -529,7 +528,7 @@ int bch2_move_ratelimit(struct btree_trans *trans, ...@@ -529,7 +528,7 @@ int bch2_move_ratelimit(struct btree_trans *trans,
schedule_timeout(delay); schedule_timeout(delay);
if (unlikely(freezing(current))) { if (unlikely(freezing(current))) {
move_ctxt_wait_event(ctxt, trans, list_empty(&ctxt->reads)); move_ctxt_wait_event(ctxt, list_empty(&ctxt->reads));
try_to_freeze(); try_to_freeze();
} }
} while (delay); } while (delay);
...@@ -538,7 +537,7 @@ int bch2_move_ratelimit(struct btree_trans *trans, ...@@ -538,7 +537,7 @@ int bch2_move_ratelimit(struct btree_trans *trans,
* XXX: these limits really ought to be per device, SSDs and hard drives * XXX: these limits really ought to be per device, SSDs and hard drives
* will want different limits * will want different limits
*/ */
move_ctxt_wait_event(ctxt, trans, move_ctxt_wait_event(ctxt,
atomic_read(&ctxt->write_sectors) < c->opts.move_bytes_in_flight >> 9 && atomic_read(&ctxt->write_sectors) < c->opts.move_bytes_in_flight >> 9 &&
atomic_read(&ctxt->read_sectors) < c->opts.move_bytes_in_flight >> 9 && atomic_read(&ctxt->read_sectors) < c->opts.move_bytes_in_flight >> 9 &&
atomic_read(&ctxt->write_ios) < c->opts.move_ios_in_flight && atomic_read(&ctxt->write_ios) < c->opts.move_ios_in_flight &&
...@@ -547,14 +546,14 @@ int bch2_move_ratelimit(struct btree_trans *trans, ...@@ -547,14 +546,14 @@ int bch2_move_ratelimit(struct btree_trans *trans,
return 0; return 0;
} }
static int bch2_move_data_btree(struct btree_trans *trans, static int bch2_move_data_btree(struct moving_context *ctxt,
struct moving_context *ctxt, struct bpos start,
struct bpos start, struct bpos end,
struct bpos end, move_pred_fn pred, void *arg,
move_pred_fn pred, void *arg, enum btree_id btree_id)
enum btree_id btree_id)
{ {
struct bch_fs *c = ctxt->c; struct btree_trans *trans = ctxt->trans;
struct bch_fs *c = trans->c;
struct per_snapshot_io_opts snapshot_io_opts; struct per_snapshot_io_opts snapshot_io_opts;
struct bch_io_opts *io_opts; struct bch_io_opts *io_opts;
struct bkey_buf sk; struct bkey_buf sk;
...@@ -579,7 +578,7 @@ static int bch2_move_data_btree(struct btree_trans *trans, ...@@ -579,7 +578,7 @@ static int bch2_move_data_btree(struct btree_trans *trans,
if (ctxt->rate) if (ctxt->rate)
bch2_ratelimit_reset(ctxt->rate); bch2_ratelimit_reset(ctxt->rate);
while (!bch2_move_ratelimit(trans, ctxt)) { while (!bch2_move_ratelimit(ctxt)) {
bch2_trans_begin(trans); bch2_trans_begin(trans);
k = bch2_btree_iter_peek(&iter); k = bch2_btree_iter_peek(&iter);
...@@ -617,15 +616,14 @@ static int bch2_move_data_btree(struct btree_trans *trans, ...@@ -617,15 +616,14 @@ static int bch2_move_data_btree(struct btree_trans *trans,
bch2_bkey_buf_reassemble(&sk, c, k); bch2_bkey_buf_reassemble(&sk, c, k);
k = bkey_i_to_s_c(sk.k); k = bkey_i_to_s_c(sk.k);
ret2 = bch2_move_extent(trans, &iter, ctxt, NULL, ret2 = bch2_move_extent(ctxt, NULL, &iter, k, *io_opts, data_opts);
*io_opts, k, data_opts);
if (ret2) { if (ret2) {
if (bch2_err_matches(ret2, BCH_ERR_transaction_restart)) if (bch2_err_matches(ret2, BCH_ERR_transaction_restart))
continue; continue;
if (ret2 == -ENOMEM) { if (ret2 == -ENOMEM) {
/* memory allocation failure, wait for some IO to finish */ /* memory allocation failure, wait for some IO to finish */
bch2_move_ctxt_wait_for_io(ctxt, trans); bch2_move_ctxt_wait_for_io(ctxt);
continue; continue;
} }
...@@ -646,13 +644,12 @@ static int bch2_move_data_btree(struct btree_trans *trans, ...@@ -646,13 +644,12 @@ static int bch2_move_data_btree(struct btree_trans *trans,
return ret; return ret;
} }
int __bch2_move_data(struct btree_trans *trans, int __bch2_move_data(struct moving_context *ctxt,
struct moving_context *ctxt,
struct bbpos start, struct bbpos start,
struct bbpos end, struct bbpos end,
move_pred_fn pred, void *arg) move_pred_fn pred, void *arg)
{ {
struct bch_fs *c = trans->c; struct bch_fs *c = ctxt->trans->c;
enum btree_id id; enum btree_id id;
int ret = 0; int ret = 0;
...@@ -665,7 +662,7 @@ int __bch2_move_data(struct btree_trans *trans, ...@@ -665,7 +662,7 @@ int __bch2_move_data(struct btree_trans *trans,
!bch2_btree_id_root(c, id)->b) !bch2_btree_id_root(c, id)->b)
continue; continue;
ret = bch2_move_data_btree(trans, ctxt, ret = bch2_move_data_btree(ctxt,
id == start.btree ? start.pos : POS_MIN, id == start.btree ? start.pos : POS_MIN,
id == end.btree ? end.pos : POS_MAX, id == end.btree ? end.pos : POS_MAX,
pred, arg, id); pred, arg, id);
...@@ -686,26 +683,23 @@ int bch2_move_data(struct bch_fs *c, ...@@ -686,26 +683,23 @@ int bch2_move_data(struct bch_fs *c,
move_pred_fn pred, void *arg) move_pred_fn pred, void *arg)
{ {
struct btree_trans *trans;
struct moving_context ctxt; struct moving_context ctxt;
int ret; int ret;
bch2_moving_ctxt_init(&ctxt, c, rate, stats, wp, wait_on_copygc); bch2_moving_ctxt_init(&ctxt, c, rate, stats, wp, wait_on_copygc);
trans = bch2_trans_get(c); ret = __bch2_move_data(&ctxt, start, end, pred, arg);
ret = __bch2_move_data(trans, &ctxt, start, end, pred, arg);
bch2_trans_put(trans);
bch2_moving_ctxt_exit(&ctxt); bch2_moving_ctxt_exit(&ctxt);
return ret; return ret;
} }
int __bch2_evacuate_bucket(struct btree_trans *trans, int __bch2_evacuate_bucket(struct moving_context *ctxt,
struct moving_context *ctxt,
struct move_bucket_in_flight *bucket_in_flight, struct move_bucket_in_flight *bucket_in_flight,
struct bpos bucket, int gen, struct bpos bucket, int gen,
struct data_update_opts _data_opts) struct data_update_opts _data_opts)
{ {
struct bch_fs *c = ctxt->c; struct btree_trans *trans = ctxt->trans;
struct bch_fs *c = trans->c;
struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts); struct bch_io_opts io_opts = bch2_opts_to_inode_opts(c->opts);
struct btree_iter iter; struct btree_iter iter;
struct bkey_buf sk; struct bkey_buf sk;
...@@ -750,7 +744,7 @@ int __bch2_evacuate_bucket(struct btree_trans *trans, ...@@ -750,7 +744,7 @@ int __bch2_evacuate_bucket(struct btree_trans *trans,
goto err; goto err;
} }
while (!(ret = bch2_move_ratelimit(trans, ctxt))) { while (!(ret = bch2_move_ratelimit(ctxt))) {
bch2_trans_begin(trans); bch2_trans_begin(trans);
ret = bch2_get_next_backpointer(trans, bucket, gen, ret = bch2_get_next_backpointer(trans, bucket, gen,
...@@ -800,16 +794,15 @@ int __bch2_evacuate_bucket(struct btree_trans *trans, ...@@ -800,16 +794,15 @@ int __bch2_evacuate_bucket(struct btree_trans *trans,
i++; i++;
} }
ret = bch2_move_extent(trans, &iter, ctxt, ret = bch2_move_extent(ctxt, bucket_in_flight,
bucket_in_flight, &iter, k, io_opts, data_opts);
io_opts, k, data_opts);
bch2_trans_iter_exit(trans, &iter); bch2_trans_iter_exit(trans, &iter);
if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
continue; continue;
if (ret == -ENOMEM) { if (ret == -ENOMEM) {
/* memory allocation failure, wait for some IO to finish */ /* memory allocation failure, wait for some IO to finish */
bch2_move_ctxt_wait_for_io(ctxt, trans); bch2_move_ctxt_wait_for_io(ctxt);
continue; continue;
} }
if (ret) if (ret)
...@@ -865,14 +858,12 @@ int bch2_evacuate_bucket(struct bch_fs *c, ...@@ -865,14 +858,12 @@ int bch2_evacuate_bucket(struct bch_fs *c,
struct write_point_specifier wp, struct write_point_specifier wp,
bool wait_on_copygc) bool wait_on_copygc)
{ {
struct btree_trans *trans = bch2_trans_get(c);
struct moving_context ctxt; struct moving_context ctxt;
int ret; int ret;
bch2_moving_ctxt_init(&ctxt, c, rate, stats, wp, wait_on_copygc); bch2_moving_ctxt_init(&ctxt, c, rate, stats, wp, wait_on_copygc);
ret = __bch2_evacuate_bucket(trans, &ctxt, NULL, bucket, gen, data_opts); ret = __bch2_evacuate_bucket(&ctxt, NULL, bucket, gen, data_opts);
bch2_moving_ctxt_exit(&ctxt); bch2_moving_ctxt_exit(&ctxt);
bch2_trans_put(trans);
return ret; return ret;
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
struct bch_read_bio; struct bch_read_bio;
struct moving_context { struct moving_context {
struct bch_fs *c; struct btree_trans *trans;
struct list_head list; struct list_head list;
void *fn; void *fn;
...@@ -38,10 +38,10 @@ struct moving_context { ...@@ -38,10 +38,10 @@ struct moving_context {
wait_queue_head_t wait; wait_queue_head_t wait;
}; };
#define move_ctxt_wait_event(_ctxt, _trans, _cond) \ #define move_ctxt_wait_event(_ctxt, _cond) \
do { \ do { \
bool cond_finished = false; \ bool cond_finished = false; \
bch2_moving_ctxt_do_pending_writes(_ctxt, _trans); \ bch2_moving_ctxt_do_pending_writes(_ctxt); \
\ \
if (_cond) \ if (_cond) \
break; \ break; \
...@@ -60,11 +60,9 @@ void bch2_moving_ctxt_init(struct moving_context *, struct bch_fs *, ...@@ -60,11 +60,9 @@ void bch2_moving_ctxt_init(struct moving_context *, struct bch_fs *,
struct bch_ratelimit *, struct bch_move_stats *, struct bch_ratelimit *, struct bch_move_stats *,
struct write_point_specifier, bool); struct write_point_specifier, bool);
struct moving_io *bch2_moving_ctxt_next_pending_write(struct moving_context *); struct moving_io *bch2_moving_ctxt_next_pending_write(struct moving_context *);
void bch2_moving_ctxt_do_pending_writes(struct moving_context *, void bch2_moving_ctxt_do_pending_writes(struct moving_context *);
struct btree_trans *); void bch2_move_ctxt_wait_for_io(struct moving_context *);
void bch2_move_ctxt_wait_for_io(struct moving_context *, int bch2_move_ratelimit(struct moving_context *);
struct btree_trans *);
int bch2_move_ratelimit(struct btree_trans *, struct moving_context *);
/* Inodes in different snapshots may have different IO options: */ /* Inodes in different snapshots may have different IO options: */
struct snapshot_io_opts_entry { struct snapshot_io_opts_entry {
...@@ -95,16 +93,14 @@ int bch2_move_get_io_opts_one(struct btree_trans *, struct bch_io_opts *, struct ...@@ -95,16 +93,14 @@ int bch2_move_get_io_opts_one(struct btree_trans *, struct bch_io_opts *, struct
int bch2_scan_old_btree_nodes(struct bch_fs *, struct bch_move_stats *); int bch2_scan_old_btree_nodes(struct bch_fs *, struct bch_move_stats *);
int bch2_move_extent(struct btree_trans *, int bch2_move_extent(struct moving_context *,
struct btree_iter *,
struct moving_context *,
struct move_bucket_in_flight *, struct move_bucket_in_flight *,
struct bch_io_opts, struct btree_iter *,
struct bkey_s_c, struct bkey_s_c,
struct bch_io_opts,
struct data_update_opts); struct data_update_opts);
int __bch2_move_data(struct btree_trans *, int __bch2_move_data(struct moving_context *,
struct moving_context *,
struct bbpos, struct bbpos,
struct bbpos, struct bbpos,
move_pred_fn, void *); move_pred_fn, void *);
...@@ -117,8 +113,7 @@ int bch2_move_data(struct bch_fs *, ...@@ -117,8 +113,7 @@ int bch2_move_data(struct bch_fs *,
bool, bool,
move_pred_fn, void *); move_pred_fn, void *);
int __bch2_evacuate_bucket(struct btree_trans *, int __bch2_evacuate_bucket(struct moving_context *,
struct moving_context *,
struct move_bucket_in_flight *, struct move_bucket_in_flight *,
struct bpos, int, struct bpos, int,
struct data_update_opts); struct data_update_opts);
......
...@@ -101,8 +101,7 @@ static int bch2_bucket_is_movable(struct btree_trans *trans, ...@@ -101,8 +101,7 @@ static int bch2_bucket_is_movable(struct btree_trans *trans,
return ret; return ret;
} }
static void move_buckets_wait(struct btree_trans *trans, static void move_buckets_wait(struct moving_context *ctxt,
struct moving_context *ctxt,
struct buckets_in_flight *list, struct buckets_in_flight *list,
bool flush) bool flush)
{ {
...@@ -111,7 +110,7 @@ static void move_buckets_wait(struct btree_trans *trans, ...@@ -111,7 +110,7 @@ static void move_buckets_wait(struct btree_trans *trans,
while ((i = list->first)) { while ((i = list->first)) {
if (flush) if (flush)
move_ctxt_wait_event(ctxt, trans, !atomic_read(&i->count)); move_ctxt_wait_event(ctxt, !atomic_read(&i->count));
if (atomic_read(&i->count)) if (atomic_read(&i->count))
break; break;
...@@ -129,7 +128,7 @@ static void move_buckets_wait(struct btree_trans *trans, ...@@ -129,7 +128,7 @@ static void move_buckets_wait(struct btree_trans *trans,
kfree(i); kfree(i);
} }
bch2_trans_unlock(trans); bch2_trans_unlock(ctxt->trans);
} }
static bool bucket_in_flight(struct buckets_in_flight *list, static bool bucket_in_flight(struct buckets_in_flight *list,
...@@ -140,11 +139,11 @@ static bool bucket_in_flight(struct buckets_in_flight *list, ...@@ -140,11 +139,11 @@ static bool bucket_in_flight(struct buckets_in_flight *list,
typedef DARRAY(struct move_bucket) move_buckets; typedef DARRAY(struct move_bucket) move_buckets;
static int bch2_copygc_get_buckets(struct btree_trans *trans, static int bch2_copygc_get_buckets(struct moving_context *ctxt,
struct moving_context *ctxt,
struct buckets_in_flight *buckets_in_flight, struct buckets_in_flight *buckets_in_flight,
move_buckets *buckets) move_buckets *buckets)
{ {
struct btree_trans *trans = ctxt->trans;
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct btree_iter iter; struct btree_iter iter;
struct bkey_s_c k; struct bkey_s_c k;
...@@ -152,7 +151,7 @@ static int bch2_copygc_get_buckets(struct btree_trans *trans, ...@@ -152,7 +151,7 @@ static int bch2_copygc_get_buckets(struct btree_trans *trans,
size_t saw = 0, in_flight = 0, not_movable = 0, sectors = 0; size_t saw = 0, in_flight = 0, not_movable = 0, sectors = 0;
int ret; int ret;
move_buckets_wait(trans, ctxt, buckets_in_flight, false); move_buckets_wait(ctxt, buckets_in_flight, false);
ret = bch2_btree_write_buffer_flush(trans); ret = bch2_btree_write_buffer_flush(trans);
if (bch2_fs_fatal_err_on(ret, c, "%s: error %s from bch2_btree_write_buffer_flush()", if (bch2_fs_fatal_err_on(ret, c, "%s: error %s from bch2_btree_write_buffer_flush()",
...@@ -188,10 +187,10 @@ static int bch2_copygc_get_buckets(struct btree_trans *trans, ...@@ -188,10 +187,10 @@ static int bch2_copygc_get_buckets(struct btree_trans *trans,
} }
noinline noinline
static int bch2_copygc(struct btree_trans *trans, static int bch2_copygc(struct moving_context *ctxt,
struct moving_context *ctxt,
struct buckets_in_flight *buckets_in_flight) struct buckets_in_flight *buckets_in_flight)
{ {
struct btree_trans *trans = ctxt->trans;
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
struct data_update_opts data_opts = { struct data_update_opts data_opts = {
.btree_insert_flags = BCH_WATERMARK_copygc, .btree_insert_flags = BCH_WATERMARK_copygc,
...@@ -202,7 +201,7 @@ static int bch2_copygc(struct btree_trans *trans, ...@@ -202,7 +201,7 @@ static int bch2_copygc(struct btree_trans *trans,
u64 moved = atomic64_read(&ctxt->stats->sectors_moved); u64 moved = atomic64_read(&ctxt->stats->sectors_moved);
int ret = 0; int ret = 0;
ret = bch2_copygc_get_buckets(trans, ctxt, buckets_in_flight, &buckets); ret = bch2_copygc_get_buckets(ctxt, buckets_in_flight, &buckets);
if (ret) if (ret)
goto err; goto err;
...@@ -221,7 +220,7 @@ static int bch2_copygc(struct btree_trans *trans, ...@@ -221,7 +220,7 @@ static int bch2_copygc(struct btree_trans *trans,
break; break;
} }
ret = __bch2_evacuate_bucket(trans, ctxt, f, f->bucket.k.bucket, ret = __bch2_evacuate_bucket(ctxt, f, f->bucket.k.bucket,
f->bucket.k.gen, data_opts); f->bucket.k.gen, data_opts);
if (ret) if (ret)
goto err; goto err;
...@@ -300,7 +299,6 @@ void bch2_copygc_wait_to_text(struct printbuf *out, struct bch_fs *c) ...@@ -300,7 +299,6 @@ void bch2_copygc_wait_to_text(struct printbuf *out, struct bch_fs *c)
static int bch2_copygc_thread(void *arg) static int bch2_copygc_thread(void *arg)
{ {
struct bch_fs *c = arg; struct bch_fs *c = arg;
struct btree_trans *trans;
struct moving_context ctxt; struct moving_context ctxt;
struct bch_move_stats move_stats; struct bch_move_stats move_stats;
struct io_clock *clock = &c->io_clock[WRITE]; struct io_clock *clock = &c->io_clock[WRITE];
...@@ -317,7 +315,6 @@ static int bch2_copygc_thread(void *arg) ...@@ -317,7 +315,6 @@ static int bch2_copygc_thread(void *arg)
} }
set_freezable(); set_freezable();
trans = bch2_trans_get(c);
bch2_move_stats_init(&move_stats, "copygc"); bch2_move_stats_init(&move_stats, "copygc");
bch2_moving_ctxt_init(&ctxt, c, NULL, &move_stats, bch2_moving_ctxt_init(&ctxt, c, NULL, &move_stats,
...@@ -325,16 +322,16 @@ static int bch2_copygc_thread(void *arg) ...@@ -325,16 +322,16 @@ static int bch2_copygc_thread(void *arg)
false); false);
while (!ret && !kthread_should_stop()) { while (!ret && !kthread_should_stop()) {
bch2_trans_unlock(trans); bch2_trans_unlock(ctxt.trans);
cond_resched(); cond_resched();
if (!c->copy_gc_enabled) { if (!c->copy_gc_enabled) {
move_buckets_wait(trans, &ctxt, &buckets, true); move_buckets_wait(&ctxt, &buckets, true);
kthread_wait_freezable(c->copy_gc_enabled); kthread_wait_freezable(c->copy_gc_enabled);
} }
if (unlikely(freezing(current))) { if (unlikely(freezing(current))) {
move_buckets_wait(trans, &ctxt, &buckets, true); move_buckets_wait(&ctxt, &buckets, true);
__refrigerator(false); __refrigerator(false);
continue; continue;
} }
...@@ -345,7 +342,7 @@ static int bch2_copygc_thread(void *arg) ...@@ -345,7 +342,7 @@ static int bch2_copygc_thread(void *arg)
if (wait > clock->max_slop) { if (wait > clock->max_slop) {
c->copygc_wait_at = last; c->copygc_wait_at = last;
c->copygc_wait = last + wait; c->copygc_wait = last + wait;
move_buckets_wait(trans, &ctxt, &buckets, true); move_buckets_wait(&ctxt, &buckets, true);
trace_and_count(c, copygc_wait, c, wait, last + wait); trace_and_count(c, copygc_wait, c, wait, last + wait);
bch2_kthread_io_clock_wait(clock, last + wait, bch2_kthread_io_clock_wait(clock, last + wait,
MAX_SCHEDULE_TIMEOUT); MAX_SCHEDULE_TIMEOUT);
...@@ -355,15 +352,14 @@ static int bch2_copygc_thread(void *arg) ...@@ -355,15 +352,14 @@ static int bch2_copygc_thread(void *arg)
c->copygc_wait = 0; c->copygc_wait = 0;
c->copygc_running = true; c->copygc_running = true;
ret = bch2_copygc(trans, &ctxt, &buckets); ret = bch2_copygc(&ctxt, &buckets);
c->copygc_running = false; c->copygc_running = false;
wake_up(&c->copygc_running_wq); wake_up(&c->copygc_running_wq);
} }
move_buckets_wait(trans, &ctxt, &buckets, true); move_buckets_wait(&ctxt, &buckets, true);
rhashtable_destroy(&buckets.table); rhashtable_destroy(&buckets.table);
bch2_trans_put(trans);
bch2_moving_ctxt_exit(&ctxt); bch2_moving_ctxt_exit(&ctxt);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment