bcachefs: Fix bch2_propagate_key_to_snapshot_leaves()
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 10 Sep 2023 20:24:02 +0000 (16:24 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:12 +0000 (17:10 -0400)
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 <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_update.c
fs/bcachefs/fsck.c
fs/bcachefs/snapshot.c

index 4469b2e166eb9be8b1d741ae1ff253e277e6bda6..b885e4e210d4891edccc696c10e480c41d8c6548 100644 (file)
@@ -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,                  \
index 880ce74318945aee7252ce0be8d669f65d0a2210..7368e1e00f53c177655087f9b0b55308195781c3 100644 (file)
@@ -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);
 }
 
 /*
index 238caeeaf06ce411a13455b74218f83ebf1126a1..ded9711e44dd4c164dea8aff9c4dd2232e3454e4 100644 (file)
@@ -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,
index 9da09911466e8a5c9dd5c8529e2b066cd2a696e3..3ca61ede28d5bcd4422bf761a0f96055805a214d 100644 (file)
@@ -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)