]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Fix for bch2_trans_commit() unlocking when it's not supposed to
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 28 Mar 2021 00:58:57 +0000 (20:58 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:57 +0000 (17:08 -0400)
When we pass BTREE_INSERT_NOUNLOCK bch2_trans_commit isn't supposed to
unlock after a successful commit, but it was calling
bch2_trans_cond_resched() - oops.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_update_leaf.c

index cf41ece0d66e91470eb599354c77490a23c03625..fb7614367e1cc0baf1895944beba351f6bc7d3a9 100644 (file)
@@ -2155,7 +2155,8 @@ void bch2_trans_reset(struct btree_trans *trans, unsigned flags)
                       (void *) &trans->fs_usage_deltas->memset_start);
        }
 
-       bch2_trans_cond_resched(trans);
+       if (!(flags & TRANS_RESET_NOUNLOCK))
+               bch2_trans_cond_resched(trans);
 
        if (!(flags & TRANS_RESET_NOTRAVERSE))
                bch2_btree_iter_traverse_all(trans);
index 8768f4cb96fae46045ab17f7ad9e493bce963eb1..176661b3b87954290bc43df25f6893c77930c594 100644 (file)
@@ -303,6 +303,7 @@ static inline void set_btree_iter_dontneed(struct btree_trans *trans, struct btr
 }
 
 #define TRANS_RESET_NOTRAVERSE         (1 << 0)
+#define TRANS_RESET_NOUNLOCK           (1 << 1)
 
 void bch2_trans_reset(struct btree_trans *, unsigned);
 
index e76916cffd5b3cd4fc6f741e6325cb5ed568d47e..62fa0d59242ab9b528403360ba76297d5bf5d3fd 100644 (file)
@@ -826,7 +826,7 @@ int __bch2_trans_commit(struct btree_trans *trans)
        struct btree_insert_entry *i = NULL;
        struct btree_iter *iter;
        bool trans_trigger_run;
-       unsigned u64s;
+       unsigned u64s, reset_flags = 0;
        int ret = 0;
 
        if (!trans->nr_updates)
@@ -940,7 +940,11 @@ out:
        if (likely(!(trans->flags & BTREE_INSERT_NOCHECK_RW)))
                percpu_ref_put(&trans->c->writes);
 out_reset:
-       bch2_trans_reset(trans, !ret ? TRANS_RESET_NOTRAVERSE : 0);
+       if (!ret)
+               reset_flags |= TRANS_RESET_NOTRAVERSE;
+       if (!ret && (trans->flags & BTREE_INSERT_NOUNLOCK))
+               reset_flags |= TRANS_RESET_NOUNLOCK;
+       bch2_trans_reset(trans, reset_flags);
 
        return ret;
 err: