bcachefs: kill move_bucket_in_flight

Small cleanup/simplification, and prep work for the next patch, which
will add checking if buckets don't get evacuated because they're missing
backpointers.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet
2025-05-08 17:01:49 -04:00
parent b42fac043f
commit 49188a9313
4 changed files with 49 additions and 57 deletions

View File

@@ -67,7 +67,7 @@ static void trace_io_move_read2(struct bch_fs *c, struct bkey_s_c k)
struct moving_io {
struct list_head read_list;
struct list_head io_list;
struct move_bucket_in_flight *b;
struct move_bucket *b;
struct closure cl;
bool read_completed;
@@ -289,7 +289,7 @@ void bch2_move_stats_init(struct bch_move_stats *stats, const char *name)
}
int bch2_move_extent(struct moving_context *ctxt,
struct move_bucket_in_flight *bucket_in_flight,
struct move_bucket *bucket_in_flight,
struct btree_iter *iter,
struct bkey_s_c k,
struct bch_io_opts io_opts,
@@ -810,7 +810,7 @@ int bch2_move_data(struct bch_fs *c,
}
static int __bch2_move_data_phys(struct moving_context *ctxt,
struct move_bucket_in_flight *bucket_in_flight,
struct move_bucket *bucket_in_flight,
unsigned dev,
u64 bucket_start,
u64 bucket_end,
@@ -1008,9 +1008,9 @@ static bool evacuate_bucket_pred(struct bch_fs *c, void *_arg,
}
int bch2_evacuate_bucket(struct moving_context *ctxt,
struct move_bucket_in_flight *bucket_in_flight,
struct bpos bucket, int gen,
struct data_update_opts data_opts)
struct move_bucket *bucket_in_flight,
struct bpos bucket, int gen,
struct data_update_opts data_opts)
{
struct evacuate_bucket_arg arg = { bucket, gen, data_opts, };

View File

@@ -116,7 +116,7 @@ int bch2_move_get_io_opts_one(struct btree_trans *, struct bch_io_opts *,
int bch2_scan_old_btree_nodes(struct bch_fs *, struct bch_move_stats *);
int bch2_move_extent(struct moving_context *,
struct move_bucket_in_flight *,
struct move_bucket *,
struct btree_iter *,
struct bkey_s_c,
struct bch_io_opts,
@@ -143,7 +143,7 @@ int bch2_move_data_phys(struct bch_fs *, unsigned, u64, u64, unsigned,
move_pred_fn, void *);
int bch2_evacuate_bucket(struct moving_context *,
struct move_bucket_in_flight *,
struct move_bucket *,
struct bpos, int,
struct data_update_opts);
int bch2_data_job(struct bch_fs *,

View File

@@ -36,14 +36,10 @@ struct move_bucket_key {
};
struct move_bucket {
struct move_bucket *next;
struct rhash_head hash;
struct move_bucket_key k;
unsigned sectors;
};
struct move_bucket_in_flight {
struct move_bucket_in_flight *next;
struct rhash_head hash;
struct move_bucket bucket;
atomic_t count;
};

View File

@@ -27,47 +27,36 @@
#include <linux/wait.h>
struct buckets_in_flight {
struct rhashtable table;
struct move_bucket_in_flight *first;
struct move_bucket_in_flight *last;
size_t nr;
size_t sectors;
struct rhashtable table;
struct move_bucket *first;
struct move_bucket *last;
size_t nr;
size_t sectors;
};
static const struct rhashtable_params bch_move_bucket_params = {
.head_offset = offsetof(struct move_bucket_in_flight, hash),
.key_offset = offsetof(struct move_bucket_in_flight, bucket.k),
.head_offset = offsetof(struct move_bucket, hash),
.key_offset = offsetof(struct move_bucket, k),
.key_len = sizeof(struct move_bucket_key),
.automatic_shrinking = true,
};
static struct move_bucket_in_flight *
move_bucket_in_flight_add(struct buckets_in_flight *list, struct move_bucket b)
static int move_bucket_in_flight_add(struct buckets_in_flight *list, struct move_bucket *b)
{
struct move_bucket_in_flight *new = kzalloc(sizeof(*new), GFP_KERNEL);
int ret;
if (!new)
return ERR_PTR(-ENOMEM);
new->bucket = b;
ret = rhashtable_lookup_insert_fast(&list->table, &new->hash,
bch_move_bucket_params);
if (ret) {
kfree(new);
return ERR_PTR(ret);
}
int ret = rhashtable_lookup_insert_fast(&list->table, &b->hash,
bch_move_bucket_params);
if (ret)
return ret;
if (!list->first)
list->first = new;
list->first = b;
else
list->last->next = new;
list->last->next = b;
list->last = new;
list->last = b;
list->nr++;
list->sectors += b.sectors;
return new;
list->sectors += b->sectors;
return 0;
}
static int bch2_bucket_is_movable(struct btree_trans *trans,
@@ -111,7 +100,7 @@ static void move_buckets_wait(struct moving_context *ctxt,
struct buckets_in_flight *list,
bool flush)
{
struct move_bucket_in_flight *i;
struct move_bucket *i;
int ret;
while ((i = list->first)) {
@@ -126,7 +115,7 @@ static void move_buckets_wait(struct moving_context *ctxt,
list->last = NULL;
list->nr--;
list->sectors -= i->bucket.sectors;
list->sectors -= i->sectors;
ret = rhashtable_remove_fast(&list->table, &i->hash,
bch_move_bucket_params);
@@ -143,7 +132,7 @@ static bool bucket_in_flight(struct buckets_in_flight *list,
return rhashtable_lookup_fast(&list->table, &k, bch_move_bucket_params);
}
typedef DARRAY(struct move_bucket) move_buckets;
typedef DARRAY(struct move_bucket *) move_buckets;
static int bch2_copygc_get_buckets(struct moving_context *ctxt,
struct buckets_in_flight *buckets_in_flight,
@@ -184,9 +173,18 @@ static int bch2_copygc_get_buckets(struct moving_context *ctxt,
else if (bucket_in_flight(buckets_in_flight, b.k))
in_flight++;
else {
ret2 = darray_push(buckets, b);
struct move_bucket *b_i = kmalloc(sizeof(*b_i), GFP_KERNEL);
ret2 = b_i ? 0 : -ENOMEM;
if (ret2)
goto err;
*b_i = b;
ret2 = darray_push(buckets, b_i);
if (ret2) {
kfree(b_i);
goto err;
}
sectors += b.sectors;
}
@@ -213,7 +211,6 @@ static int bch2_copygc(struct moving_context *ctxt,
.btree_insert_flags = BCH_WATERMARK_copygc,
};
move_buckets buckets = { 0 };
struct move_bucket_in_flight *f;
u64 sectors_seen = atomic64_read(&ctxt->stats->sectors_seen);
u64 sectors_moved = atomic64_read(&ctxt->stats->sectors_moved);
int ret = 0;
@@ -226,26 +223,23 @@ static int bch2_copygc(struct moving_context *ctxt,
if (kthread_should_stop() || freezing(current))
break;
f = move_bucket_in_flight_add(buckets_in_flight, *i);
ret = PTR_ERR_OR_ZERO(f);
if (ret == -EEXIST) { /* rare race: copygc_get_buckets returned same bucket more than once */
struct move_bucket *b = *i;
*i = NULL;
ret = move_bucket_in_flight_add(buckets_in_flight, b);
if (ret) { /* rare race: copygc_get_buckets returned same bucket more than once */
kfree(b);
ret = 0;
continue;
}
if (ret == -ENOMEM) { /* flush IO, continue later */
ret = 0;
break;
}
ret = bch2_evacuate_bucket(ctxt, f, f->bucket.k.bucket,
f->bucket.k.gen, data_opts);
ret = bch2_evacuate_bucket(ctxt, b, b->k.bucket, b->k.gen, data_opts);
if (ret)
goto err;
*did_work = true;
}
err:
/* no entries in LRU btree found, or got to end: */
if (bch2_err_matches(ret, ENOENT))
ret = 0;
@@ -257,6 +251,8 @@ err:
sectors_moved = atomic64_read(&ctxt->stats->sectors_moved) - sectors_moved;
trace_and_count(c, copygc, c, buckets.nr, sectors_seen, sectors_moved);
darray_for_each(buckets, i)
kfree(*i);
darray_exit(&buckets);
return ret;
}