From c872afa22420cbbeb8c78656926928b9e2abae18 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 10 Sep 2023 16:24:02 -0400 Subject: [PATCH] bcachefs: Fix bch2_propagate_key_to_snapshot_leaves() When we handle a transaction restart in a nested context, we need to return -BCH_ERR_transaction_restart_nested because we invalidated the outer context's iterators and locks. bch2_propagate_key_to_snapshot_leaves() wasn't doing this, this patch fixes it to use trans_was_restarted(). Signed-off-by: Kent Overstreet --- fs/bcachefs/btree_iter.h | 11 +++++------ fs/bcachefs/btree_update.c | 4 +--- fs/bcachefs/fsck.c | 13 +++---------- fs/bcachefs/snapshot.c | 4 +++- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 4469b2e166eb9..b885e4e210d48 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -276,9 +276,11 @@ int bch2_trans_relock_notrace(struct btree_trans *); void bch2_trans_unlock(struct btree_trans *); bool bch2_trans_locked(struct btree_trans *); -static inline bool trans_was_restarted(struct btree_trans *trans, u32 restart_count) +static inline int trans_was_restarted(struct btree_trans *trans, u32 restart_count) { - return restart_count != trans->restart_count; + return restart_count != trans->restart_count + ? -BCH_ERR_transaction_restart_nested + : 0; } void __noreturn bch2_trans_restart_error(struct btree_trans *, u32); @@ -707,10 +709,7 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans, if (!_ret) \ bch2_trans_verify_not_restarted(_trans, _restart_count);\ \ - if (!_ret && trans_was_restarted(_trans, _orig_restart_count)) \ - _ret = -BCH_ERR_transaction_restart_nested; \ - \ - _ret; \ + _ret ?: trans_was_restarted(_trans, _restart_count); \ }) #define for_each_btree_key2(_trans, _iter, _btree_id, \ diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c index 880ce74318945..7368e1e00f53c 100644 --- a/fs/bcachefs/btree_update.c +++ b/fs/bcachefs/btree_update.c @@ -777,9 +777,7 @@ err: } bch2_trans_iter_exit(trans, &iter); - if (!ret && trans_was_restarted(trans, restart_count)) - ret = -BCH_ERR_transaction_restart_nested; - return ret; + return ret ?: trans_was_restarted(trans, restart_count); } /* diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 238caeeaf06ce..ded9711e44dd4 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -618,10 +618,7 @@ static int get_inodes_all_snapshots(struct btree_trans *trans, w->first_this_inode = true; - if (trans_was_restarted(trans, restart_count)) - return -BCH_ERR_transaction_restart_nested; - - return 0; + return trans_was_restarted(trans, restart_count); } static struct inode_walker_entry * @@ -1089,9 +1086,7 @@ static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w) fsck_err: if (ret) bch_err_fn(c, ret); - if (!ret && trans_was_restarted(trans, restart_count)) - ret = -BCH_ERR_transaction_restart_nested; - return ret; + return ret ?: trans_was_restarted(trans, restart_count); } struct extent_end { @@ -1509,9 +1504,7 @@ static int check_subdir_count(struct btree_trans *trans, struct inode_walker *w) fsck_err: if (ret) bch_err_fn(c, ret); - if (!ret && trans_was_restarted(trans, restart_count)) - ret = -BCH_ERR_transaction_restart_nested; - return ret; + return ret ?: trans_was_restarted(trans, restart_count); } static int check_dirent_target(struct btree_trans *trans, diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index 9da09911466e8..3ca61ede28d5b 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -1637,6 +1637,7 @@ int bch2_propagate_key_to_snapshot_leaves(struct btree_trans *trans, { struct bch_fs *c = trans->c; struct bkey_buf sk; + u32 restart_count = trans->restart_count; int ret; bch2_bkey_buf_init(&sk); @@ -1659,7 +1660,8 @@ int bch2_propagate_key_to_snapshot_leaves(struct btree_trans *trans, } bch2_bkey_buf_exit(&sk, c); - return ret; + + return ret ?: trans_was_restarted(trans, restart_count); } int bch2_snapshots_read(struct bch_fs *c) -- 2.30.2