diff options
-rw-r--r-- | fs/bcachefs/bcachefs.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/ec.c | 20 |
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; |