summaryrefslogtreecommitdiff
path: root/fs/bcachefs/inode.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-11-18 03:07:40 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:46 +0300
commit96c2e01083f19c75421002bebb819a668839184e (patch)
treea788bbcf00f2110ebbcdc6e173517fa8fad29beb /fs/bcachefs/inode.c
parent42af0ad569edbfcd252e9abf0badd97b895c34be (diff)
downloadlinux-96c2e01083f19c75421002bebb819a668839184e.tar.xz
bcachefs: Fix a transaction path overflow
It turns out we need bch2_extent_trim_atomi() even when we're deleting extents one at a time because it's possible for one reflink_p to reference arbitrarily many reflink_v extents. This doesn't normally happen, but the data move path can fragment existing extents in the background. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/inode.c')
-rw-r--r--fs/bcachefs/inode.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index 4161cd850eb8..f026e2f70dcd 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -599,7 +599,6 @@ static int bch2_inode_delete_keys(struct btree_trans *trans,
* iterator:
*/
bch2_trans_iter_init(trans, &iter, id, POS(inum.inum, 0),
- BTREE_ITER_NOT_EXTENTS|
BTREE_ITER_INTENT);
while (1) {
@@ -622,6 +621,14 @@ static int bch2_inode_delete_keys(struct btree_trans *trans,
bkey_init(&delete.k);
delete.k.p = iter.pos;
+ if (iter.flags & BTREE_ITER_IS_EXTENTS) {
+ bch2_key_resize(&delete.k, k.k->p.offset - iter.pos.offset);
+
+ ret = bch2_extent_trim_atomic(trans, &iter, &delete);
+ if (ret)
+ goto err;
+ }
+
ret = bch2_trans_update(trans, &iter, &delete, 0) ?:
bch2_trans_commit(trans, NULL, NULL,
BTREE_INSERT_NOFAIL);