bcachefs: Better bch2_trans_copy_iter()

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2019-03-25 22:43:26 -04:00 committed by Kent Overstreet
parent 9e5e5b9e71
commit 7c26ecae32
2 changed files with 59 additions and 46 deletions

View File

@ -1606,7 +1606,6 @@ static inline void bch2_btree_iter_init(struct btree_trans *trans,
for (i = 0; i < ARRAY_SIZE(iter->l); i++) for (i = 0; i < ARRAY_SIZE(iter->l); i++)
iter->l[i].b = NULL; iter->l[i].b = NULL;
iter->l[iter->level].b = BTREE_ITER_NOT_END; iter->l[iter->level].b = BTREE_ITER_NOT_END;
iter->next = iter;
prefetch(c->btree_roots[btree_id].b); prefetch(c->btree_roots[btree_id].b);
} }
@ -1638,11 +1637,11 @@ static void bch2_btree_iter_link(struct btree_iter *iter, struct btree_iter *new
iter->next = new; iter->next = new;
} }
void bch2_btree_iter_copy(struct btree_iter *dst, struct btree_iter *src) static void __bch2_btree_iter_copy(struct btree_iter *dst,
struct btree_iter *src)
{ {
unsigned i; unsigned i;
__bch2_btree_iter_unlock(dst);
memcpy(dst, src, offsetof(struct btree_iter, next)); memcpy(dst, src, offsetof(struct btree_iter, next));
for (i = 0; i < BTREE_MAX_DEPTH; i++) for (i = 0; i < BTREE_MAX_DEPTH; i++)
@ -1651,6 +1650,12 @@ void bch2_btree_iter_copy(struct btree_iter *dst, struct btree_iter *src)
__btree_lock_want(dst, i)); __btree_lock_want(dst, i));
} }
void bch2_btree_iter_copy(struct btree_iter *dst, struct btree_iter *src)
{
__bch2_btree_iter_unlock(dst);
__bch2_btree_iter_copy(dst, src);
}
/* new transactional stuff: */ /* new transactional stuff: */
static void btree_trans_verify(struct btree_trans *trans) static void btree_trans_verify(struct btree_trans *trans)
@ -1789,6 +1794,35 @@ void bch2_trans_preload_iters(struct btree_trans *trans)
btree_trans_realloc_iters(trans, BTREE_ITER_MAX); btree_trans_realloc_iters(trans, BTREE_ITER_MAX);
} }
static int btree_trans_iter_alloc(struct btree_trans *trans)
{
struct btree_iter *iter;
unsigned idx = ffz(trans->iters_linked);
if (idx < trans->nr_iters)
goto got_slot;
if (trans->nr_iters == trans->size) {
int ret = btree_trans_realloc_iters(trans, trans->size * 2);
if (ret)
return ret;
}
idx = trans->nr_iters++;
BUG_ON(trans->nr_iters > trans->size);
got_slot:
iter = &trans->iters[idx];
iter->next = iter;
BUG_ON(trans->iters_linked & (1ULL << idx));
if (trans->iters_linked)
bch2_btree_iter_link(&trans->iters[__ffs(trans->iters_linked)],
&trans->iters[idx]);
trans->iters_linked |= 1ULL << idx;
return idx;
}
static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans, static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans,
unsigned btree_id, struct bpos pos, unsigned btree_id, struct bpos pos,
unsigned flags, u64 iter_id) unsigned flags, u64 iter_id)
@ -1799,6 +1833,9 @@ static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans,
BUG_ON(trans->nr_iters > BTREE_ITER_MAX); BUG_ON(trans->nr_iters > BTREE_ITER_MAX);
for (idx = 0; idx < trans->nr_iters; idx++) { for (idx = 0; idx < trans->nr_iters; idx++) {
if (!(trans->iters_linked & (1ULL << idx)))
continue;
iter = &trans->iters[idx]; iter = &trans->iters[idx];
if (iter_id if (iter_id
? iter->id == iter_id ? iter->id == iter_id
@ -1809,22 +1846,10 @@ static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans,
idx = -1; idx = -1;
found: found:
if (idx < 0) { if (idx < 0) {
idx = ffz(trans->iters_linked); idx = btree_trans_iter_alloc(trans);
if (idx < trans->nr_iters) if (idx < 0)
goto got_slot; return ERR_PTR(idx);
BUG_ON(trans->nr_iters > trans->size);
if (trans->nr_iters == trans->size) {
int ret = btree_trans_realloc_iters(trans,
trans->size * 2);
if (ret)
return ERR_PTR(ret);
}
idx = trans->nr_iters++;
BUG_ON(trans->nr_iters > trans->size);
got_slot:
iter = &trans->iters[idx]; iter = &trans->iters[idx];
iter->id = iter_id; iter->id = iter_id;
@ -1841,13 +1866,6 @@ got_slot:
trans->iters_live |= 1ULL << idx; trans->iters_live |= 1ULL << idx;
trans->iters_touched |= 1ULL << idx; trans->iters_touched |= 1ULL << idx;
if (trans->iters_linked &&
!(trans->iters_linked & (1 << idx)))
bch2_btree_iter_link(&trans->iters[__ffs(trans->iters_linked)],
iter);
trans->iters_linked |= 1ULL << idx;
btree_trans_verify(trans); btree_trans_verify(trans);
BUG_ON(iter->btree_id != btree_id); BUG_ON(iter->btree_id != btree_id);
@ -1894,20 +1912,22 @@ struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *trans,
return iter; return iter;
} }
struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *bch2_trans_copy_iter(struct btree_trans *trans,
struct btree_iter *src, struct btree_iter *src)
u64 iter_id)
{ {
struct btree_iter *iter = int idx;
__btree_trans_get_iter(trans, src->btree_id,
POS_MIN, src->flags, iter_id);
if (!IS_ERR(iter)) { idx = btree_trans_iter_alloc(trans);
trans->iters_unlink_on_restart |= if (idx < 0)
1ULL << btree_trans_iter_idx(trans, iter); return ERR_PTR(idx);
bch2_btree_iter_copy(iter, src);
} trans->iters_live |= 1ULL << idx;
return iter; trans->iters_touched |= 1ULL << idx;
trans->iters_unlink_on_restart |= 1ULL << idx;
__bch2_btree_iter_copy(&trans->iters[idx], src);
return &trans->iters[idx];
} }
void *bch2_trans_kmalloc(struct btree_trans *trans, void *bch2_trans_kmalloc(struct btree_trans *trans,

View File

@ -268,8 +268,8 @@ void bch2_trans_unlink_iters(struct btree_trans *, u64);
struct btree_iter *__bch2_trans_get_iter(struct btree_trans *, enum btree_id, struct btree_iter *__bch2_trans_get_iter(struct btree_trans *, enum btree_id,
struct bpos, unsigned, u64); struct bpos, unsigned, u64);
struct btree_iter *__bch2_trans_copy_iter(struct btree_trans *, struct btree_iter *bch2_trans_copy_iter(struct btree_trans *,
struct btree_iter *, u64); struct btree_iter *);
static __always_inline u64 __btree_iter_id(void) static __always_inline u64 __btree_iter_id(void)
{ {
@ -290,13 +290,6 @@ bch2_trans_get_iter(struct btree_trans *trans, enum btree_id btree_id,
__btree_iter_id()); __btree_iter_id());
} }
static __always_inline struct btree_iter *
bch2_trans_copy_iter(struct btree_trans *trans, struct btree_iter *src)
{
return __bch2_trans_copy_iter(trans, src, __btree_iter_id());
}
struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *, struct btree_iter *bch2_trans_get_node_iter(struct btree_trans *,
enum btree_id, struct bpos, enum btree_id, struct bpos,
unsigned, unsigned, unsigned); unsigned, unsigned, unsigned);