bcachefs: Don't run indirect extent trigger unless inserting/deleting
This fixes a transaction path overflow reported in the snapshot deletion path, when moving extents to the correct snapshot. The root of the issue is that creating/deleting a reflink pointer can generate an unbounded number of updates, if it is allowed to reference an unbounded number of indirect extents; to prevent this, merging of reflink pointers has been disabled. But there's a hole, which is that copygc/rebalance may fragment existing extents in the course of moving them around, and if an indirect extent becomes too fragmented we'll then become unable to delete the reflink pointer. The eventual solution is going to be to tweak trigger handling so that we can process large reflink pointers incrementally when necessary, and notice that trigger updates don't need to be run for the part of the reflink pointer not changing. That is going to be a bigger project though, for another patch. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
adcf4ee642
commit
f88d811a23
@ -121,6 +121,14 @@ int bch2_trans_mark_reflink_v(struct btree_trans *trans,
|
||||
{
|
||||
check_indirect_extent_deleting(new, &flags);
|
||||
|
||||
if (old.k->type == KEY_TYPE_reflink_v &&
|
||||
new->k.type == KEY_TYPE_reflink_v &&
|
||||
old.k->u64s == new->k.u64s &&
|
||||
!memcmp(bkey_s_c_to_reflink_v(old).v->start,
|
||||
bkey_i_to_reflink_v(new)->v.start,
|
||||
bkey_val_bytes(&new->k) - 8))
|
||||
return 0;
|
||||
|
||||
return bch2_trans_mark_extent(trans, btree_id, level, old, new, flags);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user