struct bch_stripe *v,
struct bkey_s_c k)
{
- struct bkey_s_c_extent e;
- const struct bch_extent_ptr *ptr;
- int idx;
- if (!bkey_extent_is_data(k.k))
- return -1;
-
- e = bkey_s_c_to_extent(k);
+ switch (k.k->type) {
+ case KEY_TYPE_extent: {
+ struct bkey_s_c_extent e = bkey_s_c_to_extent(k);
+ const struct bch_extent_ptr *ptr;
+ int idx;
- extent_for_each_ptr(e, ptr) {
- idx = ptr_matches_stripe(c, v, ptr);
- if (idx >= 0)
- return idx;
+ extent_for_each_ptr(e, ptr) {
+ idx = ptr_matches_stripe(c, v, ptr);
+ if (idx >= 0)
+ return idx;
+ }
+ break;
+ }
}
return -1;
static bool extent_has_stripe_ptr(struct bkey_s_c k, u64 idx)
{
- struct bkey_s_c_extent e;
- const union bch_extent_entry *entry;
-
- if (!bkey_extent_is_data(k.k))
- return false;
+ switch (k.k->type) {
+ case KEY_TYPE_extent: {
+ struct bkey_s_c_extent e = bkey_s_c_to_extent(k);
+ const union bch_extent_entry *entry;
- e = bkey_s_c_to_extent(k);
+ extent_for_each_entry(e, entry)
+ if (extent_entry_type(entry) ==
+ BCH_EXTENT_ENTRY_stripe_ptr &&
+ entry->stripe_ptr.idx == idx)
+ return true;
- extent_for_each_entry(e, entry)
- if (extent_entry_type(entry) ==
- BCH_EXTENT_ENTRY_stripe_ptr &&
- entry->stripe_ptr.idx == idx)
- return true;
+ break;
+ }
+ }
return false;
}
{
ec_stripes_heap *h = &c->ec_stripes_heap;
- return h->data[0].blocks_nonempty == 0 ? h->data[0].idx : -1;
+ return h->used && h->data[0].blocks_nonempty == 0
+ ? h->data[0].idx : -1;
}
static inline int ec_stripes_heap_cmp(ec_stripes_heap *h,
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;
err:
if (ret == -EINTR)
goto retry;
+
+ c->ec_stripe_hint = ret ? start_pos.offset : start_pos.offset + 1;
bch2_trans_exit(&trans);
return ret;
struct ec_stripe_new *s = NULL;
mutex_lock(&h->lock);
- bch2_open_buckets_stop_dev(c, ca,
- &h->blocks,
- BCH_DATA_USER);
- bch2_open_buckets_stop_dev(c, ca,
- &h->parity,
- BCH_DATA_USER);
+ bch2_open_buckets_stop_dev(c, ca, &h->blocks);
+ bch2_open_buckets_stop_dev(c, ca, &h->parity);
if (!h->s)
goto unlock;
int bch2_stripes_read(struct bch_fs *c, struct journal_keys *journal_keys)
{
- struct journal_key *i;
struct btree_trans trans;
- struct btree_iter *iter;
- struct bkey_s_c k;
+ struct btree_iter *btree_iter;
+ struct journal_iter journal_iter;
+ struct bkey_s_c btree_k, journal_k, k;
int ret;
ret = bch2_fs_ec_start(c);
bch2_trans_init(&trans, c, 0, 0);
- for_each_btree_key(&trans, iter, BTREE_ID_EC, POS_MIN, 0, k, ret)
- bch2_mark_key(c, k, 0, NULL, 0,
+ btree_iter = bch2_trans_get_iter(&trans, BTREE_ID_EC, POS_MIN, 0);
+ journal_iter = bch2_journal_iter_init(journal_keys, BTREE_ID_EC);
+
+ btree_k = bch2_btree_iter_peek(btree_iter);
+ journal_k = bch2_journal_iter_peek(&journal_iter);
+
+ while (1) {
+ if (btree_k.k && journal_k.k) {
+ int cmp = bkey_cmp(btree_k.k->p, journal_k.k->p);
+
+ if (cmp < 0) {
+ k = btree_k;
+ btree_k = bch2_btree_iter_next(btree_iter);
+ } else if (cmp == 0) {
+ btree_k = bch2_btree_iter_next(btree_iter);
+ k = journal_k;
+ journal_k = bch2_journal_iter_next(&journal_iter);
+ } else {
+ k = journal_k;
+ journal_k = bch2_journal_iter_next(&journal_iter);
+ }
+ } else if (btree_k.k) {
+ k = btree_k;
+ btree_k = bch2_btree_iter_next(btree_iter);
+ } else if (journal_k.k) {
+ k = journal_k;
+ journal_k = bch2_journal_iter_next(&journal_iter);
+ } else {
+ break;
+ }
+
+ bch2_mark_key(c, k, 0, 0, NULL, 0,
BCH_BUCKET_MARK_ALLOC_READ|
BCH_BUCKET_MARK_NOATOMIC);
+ }
ret = bch2_trans_exit(&trans) ?: ret;
if (ret) {
return ret;
}
- for_each_journal_key(*journal_keys, i)
- if (i->btree_id == BTREE_ID_EC)
- bch2_mark_key(c, bkey_i_to_s_c(i->k),
- 0, NULL, 0,
- BCH_BUCKET_MARK_ALLOC_READ|
- BCH_BUCKET_MARK_NOATOMIC);
-
return 0;
}