bcachefs: Add a hint for allocating new stripes
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 22 Aug 2019 21:09:16 +0000 (17:09 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:26 +0000 (17:08 -0400)
This way we aren't doing a full linear scan every time we create a new
stripe.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/ec.c

index 410fce3ed8d4d3f753853e54e7c54b2cf000dd7e..9bee837dedcfe7ffc7566a024ebe2f24303a0cd1 100644 (file)
@@ -745,6 +745,7 @@ struct bch_fs {
        /* ERASURE CODING */
        struct list_head        ec_new_stripe_list;
        struct mutex            ec_new_stripe_lock;
+       u64                     ec_stripe_hint;
 
        struct bio_set          ec_bioset;
 
index 2eb33a8460c9c9fa222900f8b9cdaaa2d18aa962..a9759c2ed7ab5e15bb6d5a65eea2fe2e697310cf 100644 (file)
@@ -704,26 +704,34 @@ static int ec_stripe_bkey_insert(struct bch_fs *c,
        struct btree_trans trans;
        struct btree_iter *iter;
        struct bkey_s_c k;
+       struct bpos start_pos = POS(0, c->ec_stripe_hint);
        int ret;
 
        bch2_trans_init(&trans, c, 0, 0);
 retry:
        bch2_trans_begin(&trans);
 
-       /* XXX: start pos hint */
-       for_each_btree_key(&trans, iter, BTREE_ID_EC, POS_MIN,
+       for_each_btree_key(&trans, iter, BTREE_ID_EC, start_pos,
                           BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k, ret) {
-               if (bkey_cmp(k.k->p, POS(0, U32_MAX)) > 0)
+               if (bkey_cmp(k.k->p, POS(0, U32_MAX)) > 0) {
+                       if (start_pos.offset) {
+                               start_pos = POS_MIN;
+                               bch2_btree_iter_set_pos(iter, start_pos);
+                               continue;
+                       }
+
+                       ret = -ENOSPC;
                        break;
+               }
 
                if (bkey_deleted(k.k))
                        goto found_slot;
        }
 
-       if (!ret)
-               ret = -ENOSPC;
        goto err;
 found_slot:
+       start_pos = iter->pos;
+
        ret = ec_stripe_mem_alloc(c, iter);
        if (ret)
                goto err;
@@ -738,6 +746,8 @@ found_slot:
 err:
        if (ret == -EINTR)
                goto retry;
+
+       c->ec_stripe_hint = ret ? start_pos.offset : start_pos.offset + 1;
        bch2_trans_exit(&trans);
 
        return ret;