summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-08-22 17:09:16 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:26 -0400
commit4e1510c3e9a053edc1fdfe56fc96009919ceebd8 (patch)
tree5bafe6f114442e954908675a362cd09d3a6643c4 /fs
parent3fb5ebcdd4b0599ba8d20a322d322f3a1aaea381 (diff)
downloadlwn-4e1510c3e9a053edc1fdfe56fc96009919ceebd8.tar.gz
lwn-4e1510c3e9a053edc1fdfe56fc96009919ceebd8.zip
bcachefs: Add a hint for allocating new stripes
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/bcachefs.h1
-rw-r--r--fs/bcachefs/ec.c20
2 files changed, 16 insertions, 5 deletions
diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h
index 410fce3ed8d4..9bee837dedcf 100644
--- a/fs/bcachefs/bcachefs.h
+++ b/fs/bcachefs/bcachefs.h
@@ -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;
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
index 2eb33a8460c9..a9759c2ed7ab 100644
--- a/fs/bcachefs/ec.c
+++ b/fs/bcachefs/ec.c
@@ -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;