mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-15 07:04:44 +00:00
bcachefs: Count iterators for reflink_p overwrites correctly
In order to avoid trying to allocate too many btree iterators, bch2_extent_atomic_end() needs to count how many iterators are going to be needed for insertions and overwrites - but we weren't counting the iterators for deleting a reflink_v when the refcount goes to 0. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
fb975d14b7
commit
fe9cdf61cc
1 changed files with 25 additions and 10 deletions
|
@ -935,12 +935,13 @@ static unsigned bch2_bkey_nr_alloc_ptrs(struct bkey_s_c k)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int __bch2_extent_atomic_end(struct btree_trans *trans,
|
||||
struct bkey_s_c k,
|
||||
unsigned offset,
|
||||
struct bpos *end,
|
||||
unsigned *nr_iters,
|
||||
unsigned max_iters)
|
||||
static int count_iters_for_insert(struct btree_trans *trans,
|
||||
struct bkey_s_c k,
|
||||
unsigned offset,
|
||||
struct bpos *end,
|
||||
unsigned *nr_iters,
|
||||
unsigned max_iters,
|
||||
bool overwrite)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -970,6 +971,20 @@ static int __bch2_extent_atomic_end(struct btree_trans *trans,
|
|||
break;
|
||||
|
||||
*nr_iters += 1;
|
||||
|
||||
if (overwrite &&
|
||||
k.k->type == KEY_TYPE_reflink_v) {
|
||||
struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
|
||||
|
||||
if (le64_to_cpu(r.v->refcount) == 1)
|
||||
*nr_iters += bch2_bkey_nr_alloc_ptrs(k);
|
||||
}
|
||||
|
||||
/*
|
||||
* if we're going to be deleting an entry from
|
||||
* the reflink btree, need more iters...
|
||||
*/
|
||||
|
||||
if (*nr_iters >= max_iters) {
|
||||
struct bpos pos = bkey_start_pos(k.k);
|
||||
pos.offset += r_k.k->p.offset - idx;
|
||||
|
@ -1004,8 +1019,8 @@ int bch2_extent_atomic_end(struct btree_iter *iter,
|
|||
|
||||
*end = bpos_min(insert->k.p, b->key.k.p);
|
||||
|
||||
ret = __bch2_extent_atomic_end(trans, bkey_i_to_s_c(insert),
|
||||
0, end, &nr_iters, 10);
|
||||
ret = count_iters_for_insert(trans, bkey_i_to_s_c(insert),
|
||||
0, end, &nr_iters, 10, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1024,8 +1039,8 @@ int bch2_extent_atomic_end(struct btree_iter *iter,
|
|||
offset = bkey_start_offset(&insert->k) -
|
||||
bkey_start_offset(k.k);
|
||||
|
||||
ret = __bch2_extent_atomic_end(trans, k, offset,
|
||||
end, &nr_iters, 20);
|
||||
ret = count_iters_for_insert(trans, k, offset,
|
||||
end, &nr_iters, 20, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
Loading…
Reference in a new issue