Commit fe9cdf61 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent fb975d14
...@@ -935,12 +935,13 @@ static unsigned bch2_bkey_nr_alloc_ptrs(struct bkey_s_c k) ...@@ -935,12 +935,13 @@ static unsigned bch2_bkey_nr_alloc_ptrs(struct bkey_s_c k)
return ret; return ret;
} }
static int __bch2_extent_atomic_end(struct btree_trans *trans, static int count_iters_for_insert(struct btree_trans *trans,
struct bkey_s_c k, struct bkey_s_c k,
unsigned offset, unsigned offset,
struct bpos *end, struct bpos *end,
unsigned *nr_iters, unsigned *nr_iters,
unsigned max_iters) unsigned max_iters,
bool overwrite)
{ {
int ret = 0; int ret = 0;
...@@ -970,6 +971,20 @@ static int __bch2_extent_atomic_end(struct btree_trans *trans, ...@@ -970,6 +971,20 @@ static int __bch2_extent_atomic_end(struct btree_trans *trans,
break; break;
*nr_iters += 1; *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) { if (*nr_iters >= max_iters) {
struct bpos pos = bkey_start_pos(k.k); struct bpos pos = bkey_start_pos(k.k);
pos.offset += r_k.k->p.offset - idx; pos.offset += r_k.k->p.offset - idx;
...@@ -1004,8 +1019,8 @@ int bch2_extent_atomic_end(struct btree_iter *iter, ...@@ -1004,8 +1019,8 @@ int bch2_extent_atomic_end(struct btree_iter *iter,
*end = bpos_min(insert->k.p, b->key.k.p); *end = bpos_min(insert->k.p, b->key.k.p);
ret = __bch2_extent_atomic_end(trans, bkey_i_to_s_c(insert), ret = count_iters_for_insert(trans, bkey_i_to_s_c(insert),
0, end, &nr_iters, 10); 0, end, &nr_iters, 10, false);
if (ret) if (ret)
return ret; return ret;
...@@ -1024,8 +1039,8 @@ int bch2_extent_atomic_end(struct btree_iter *iter, ...@@ -1024,8 +1039,8 @@ int bch2_extent_atomic_end(struct btree_iter *iter,
offset = bkey_start_offset(&insert->k) - offset = bkey_start_offset(&insert->k) -
bkey_start_offset(k.k); bkey_start_offset(k.k);
ret = __bch2_extent_atomic_end(trans, k, offset, ret = count_iters_for_insert(trans, k, offset,
end, &nr_iters, 20); end, &nr_iters, 20, true);
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment