summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-12-20 16:35:24 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:33 -0400
commita8abd3a7f63efe4a366ae5aba10b2466feba39d7 (patch)
treeea1d23cd85f294ca2ea459949f495f207978d8e6
parent780c4e43f8f8986bb8d97d654cb17edd0dfca4b4 (diff)
downloadlinux-stable-a8abd3a7f63efe4a366ae5aba10b2466feba39d7.tar.gz
linux-stable-a8abd3a7f63efe4a366ae5aba10b2466feba39d7.tar.bz2
linux-stable-a8abd3a7f63efe4a366ae5aba10b2466feba39d7.zip
bcachefs: bch2_trans_reset() calls should be at the tops of loops
It needs to be called when we get -EINTR due to e.g. lock restart - this fixes a transaction iterators overflow bug. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/btree_iter.h5
-rw-r--r--fs/bcachefs/btree_update_leaf.c2
-rw-r--r--fs/bcachefs/fs-io.c4
-rw-r--r--fs/bcachefs/io.c8
-rw-r--r--fs/bcachefs/reflink.c3
5 files changed, 10 insertions, 12 deletions
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index a05e542b3792..2bbf714c9698 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -299,11 +299,6 @@ static inline void bch2_trans_begin(struct btree_trans *trans)
return bch2_trans_reset(trans, TRANS_RESET_ITERS|TRANS_RESET_MEM);
}
-static inline void bch2_trans_begin_updates(struct btree_trans *trans)
-{
- return bch2_trans_reset(trans, TRANS_RESET_MEM);
-}
-
void *bch2_trans_kmalloc(struct btree_trans *, size_t);
void bch2_trans_init(struct btree_trans *, struct bch_fs *, unsigned, size_t);
int bch2_trans_exit(struct btree_trans *);
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index d13f1fc75bdf..55f785dadaac 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -869,6 +869,8 @@ retry:
bkey_cmp(iter->pos, end) < 0) {
struct bkey_i delete;
+ bch2_trans_reset(trans, TRANS_RESET_MEM);
+
bkey_init(&delete.k);
/*
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index c30c028c869d..5656e26540fa 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -2650,6 +2650,8 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
struct bkey_i_reservation reservation;
struct bkey_s_c k;
+ bch2_trans_reset(&trans, TRANS_RESET_MEM);
+
k = bch2_btree_iter_peek_slot(iter);
if ((ret = bkey_err(k)))
goto bkey_err;
@@ -2696,8 +2698,6 @@ static long bchfs_fallocate(struct bch_inode_info *inode, int mode,
reservation.v.nr_replicas = disk_res.nr_replicas;
}
- bch2_trans_begin_updates(&trans);
-
ret = bch2_extent_update(&trans, iter, &reservation.k_i,
&disk_res, &inode->ei_journal_seq,
0, &i_sectors_delta);
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index e98ab738cd10..6e0444f3c4f9 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -336,6 +336,8 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
bch2_disk_reservation_init(c, 0);
struct bkey_i delete;
+ bch2_trans_reset(trans, TRANS_RESET_MEM);
+
ret = bkey_err(k);
if (ret)
goto btree_err;
@@ -347,8 +349,6 @@ int bch2_fpunch_at(struct btree_trans *trans, struct btree_iter *iter,
bch2_key_resize(&delete.k, max_sectors);
bch2_cut_back(end, &delete);
- bch2_trans_begin_updates(trans);
-
ret = bch2_extent_update(trans, iter, &delete,
&disk_res, journal_seq,
0, i_sectors_delta);
@@ -410,14 +410,14 @@ int bch2_write_index_default(struct bch_write_op *op)
BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
do {
+ bch2_trans_reset(&trans, TRANS_RESET_MEM);
+
k = bch2_keylist_front(keys);
bkey_on_stack_realloc(&sk, c, k->k.u64s);
bkey_copy(sk.k, k);
bch2_cut_front(iter->pos, sk.k);
- bch2_trans_begin_updates(&trans);
-
ret = bch2_extent_update(&trans, iter, sk.k,
&op->res, op_journal_seq(op),
op->new_i_size, &op->i_sectors_delta);
diff --git a/fs/bcachefs/reflink.c b/fs/bcachefs/reflink.c
index 53bd0e0ea058..a65ada691ba1 100644
--- a/fs/bcachefs/reflink.c
+++ b/fs/bcachefs/reflink.c
@@ -185,7 +185,8 @@ s64 bch2_remap_range(struct bch_fs *c,
BTREE_ITER_INTENT);
while (1) {
- bch2_trans_begin_updates(&trans);
+ bch2_trans_reset(&trans, TRANS_RESET_MEM);
+
trans.mem_top = 0;
if (fatal_signal_pending(current)) {