]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: kill move_bucket_in_flight
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 8 May 2025 21:01:49 +0000 (17:01 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:57 +0000 (20:14 -0400)
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>
fs/bcachefs/move.c
fs/bcachefs/move.h
fs/bcachefs/move_types.h
fs/bcachefs/movinggc.c

index 42076aa3438b5c4f7e50376516fca0f5e8068511..3a92eced2e67b11eb93f5cd2dea18ac986a2f142 100644 (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, };
 
index 0c620a5f728d72cf5dfc345935a2066276f92601..fb38383ffc7b7d769bd8491b970fc502016e1ce3 100644 (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 *,
index 807f779f6f767bc5e5df4e5596d81a73627094c9..c5c62cd600de1c80d6922c0d3f3acd76a849cc84 100644 (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;
 };
 
index 66f4920552c557255b71b50e151e8a7e72b73854..dd07816401be4df7247e51ccdd86b5e7d55cd346 100644 (file)
 #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_bucketk),
        .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;
 }