bcachefs: Add assert for use of journal replay keys for updates
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 31 Oct 2024 07:35:41 +0000 (03:35 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:16 +0000 (01:36 -0500)
The journal replay keys mechanism can only be used for updates in early
recovery, when still single threaded.

Add some asserts to make sure we never accidentally use it elsewhere.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/super.c

index e1ab67c533f012217238418968d267bf63b9d03d..c59a58b93a92095cdec799202be9dbe712864c46 100644 (file)
@@ -743,6 +743,12 @@ struct bch_fs {
 #else
        struct percpu_ref       writes;
 #endif
+       /*
+        * Certain operations are only allowed in single threaded mode, during
+        * recovery, and we want to assert that this is the case:
+        */
+       struct task_struct      *recovery_task;
+
        /*
         * Analagous to c->writes, for asynchronous ops that don't necessarily
         * need fs to be read-write
index b47f11881fe4ae177000944ac85fca91550612df..529a5a19ab8a16f9b745dd78ea58efcff4e0f369 100644 (file)
@@ -999,6 +999,8 @@ do_bch2_trans_commit_to_journal_replay(struct btree_trans *trans)
 {
        struct bch_fs *c = trans->c;
 
+       BUG_ON(current != c->recovery_task);
+
        trans_for_each_update(trans, i) {
                int ret = bch2_journal_key_insert(c, i->btree_id, i->level, i->k);
                if (ret)
index 7e2431de3a940bf25f18087b83a5c59edbe9dcbc..7e0ff17a6dbb21ad6b4911cacc21ec36a4162133 100644 (file)
@@ -441,6 +441,8 @@ static int __bch2_fs_read_write(struct bch_fs *c, bool early)
 {
        int ret;
 
+       BUG_ON(!test_bit(BCH_FS_may_go_rw, &c->flags));
+
        if (test_bit(BCH_FS_initial_gc_unfixed, &c->flags)) {
                bch_err(c, "cannot go rw, unfixed btree errors");
                return -BCH_ERR_erofs_unfixed_errors;
@@ -1031,9 +1033,12 @@ int bch2_fs_start(struct bch_fs *c)
                bch2_dev_allocator_add(c, ca);
        bch2_recalc_capacity(c);
 
+       c->recovery_task = current;
        ret = BCH_SB_INITIALIZED(c->disk_sb.sb)
                ? bch2_fs_recovery(c)
                : bch2_fs_initialize(c);
+       c->recovery_task = NULL;
+
        if (ret)
                goto err;