]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: init freespace inited bits to 0 in bch2_fs_initialize
authorPiotr Zalewski <pZ010001011111@proton.me>
Sat, 26 Oct 2024 00:15:49 +0000 (00:15 +0000)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 29 Oct 2024 10:34:10 +0000 (06:34 -0400)
Initialize freespace_initialized bits to 0 in member's flags and update
member's cached version for each device in bch2_fs_initialize.

It's possible for the bits to be set to 1 before fs is initialized and if
call to bch2_trans_mark_dev_sbs (just before bch2_fs_freespace_init) fails
bits remain to be 1 which can later indirectly trigger BUG condition in
bch2_bucket_alloc_freelist during shutdown.

Reported-by: syzbot+2b6a17991a6af64f9489@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2b6a17991a6af64f9489
Fixes: bbe682c76789 ("bcachefs: Ensure devices are always correctly initialized")
Suggested-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Piotr Zalewski <pZ010001011111@proton.me>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/recovery.c

index 0ebc76dd7eb5b0b4fc0bdcc4c70195a80655d4f5..32d15aacc06986d7ab01e41b5a18dc93ff7a35ef 100644 (file)
@@ -1001,6 +1001,7 @@ int bch2_fs_initialize(struct bch_fs *c)
        struct bch_inode_unpacked root_inode, lostfound_inode;
        struct bkey_inode_buf packed_inode;
        struct qstr lostfound = QSTR("lost+found");
+       struct bch_member *m;
        int ret;
 
        bch_notice(c, "initializing new filesystem");
@@ -1017,6 +1018,14 @@ int bch2_fs_initialize(struct bch_fs *c)
                SET_BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb, bcachefs_metadata_version_current);
                bch2_write_super(c);
        }
+
+       for_each_member_device(c, ca) {
+               m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);
+               SET_BCH_MEMBER_FREESPACE_INITIALIZED(m, false);
+               ca->mi = bch2_mi_to_cpu(m);
+       }
+
+       bch2_write_super(c);
        mutex_unlock(&c->sb_lock);
 
        c->curr_recovery_pass = BCH_RECOVERY_PASS_NR;