]> git.hungrycats.org Git - linux/commitdiff
Snapshot create NULL pointer dereference
authorQu WenRuo <wqu@suse.com>
Tue, 10 Dec 2019 08:55:00 +0000 (08:55 +0000)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Sat, 14 Dec 2019 04:50:03 +0000 (23:50 -0500)
--YVy2ZwhygmFTft9qf4qxad0AgZTGdqI77
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

Hi,

With reproducer, I got my new fixes for all the mess I created.

Yep, that's definitely that lifespan patch caused all these problems.

I got a fix for it to pass the super fast crash script, would you please
try to test it?

Currently the only problem is, I have observed cases where metadata
balance could fall into dead loop. But since it's also reported before,
so I'm not sure if it's my fix worsen the situation.

And since I have only seen 3 different KASAN reports, with some not
reported by you, so I'm not 100% sure if all cases are covered.

Your test would help a lot to verify the fix.

Thanks,
Qu

(cherry picked from commit d595e06eefca762e4c5937d9a83b300f7c06ff31)

fs/btrfs/relocation.c

index c58245797f30af0c87b12e2c81fa98e4cbbe5a30..2b6189e646b6df03c746c5007426df77ae910779 100644 (file)
@@ -529,6 +529,9 @@ static int should_ignore_root(struct btrfs_root *root)
        if (!reloc_root)
                return 0;
 
+       if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
+               return 1;
+
        if (btrfs_root_last_snapshot(&reloc_root->root_item) ==
            root->fs_info->running_transaction->transid - 1)
                return 0;
@@ -4718,7 +4721,8 @@ void btrfs_reloc_pre_snapshot(struct btrfs_pending_snapshot *pending,
        struct btrfs_root *root = pending->root;
        struct reloc_control *rc = root->fs_info->reloc_ctl;
 
-       if (!root->reloc_root || !rc)
+       if (!root->reloc_root || !rc || test_bit(BTRFS_ROOT_DEAD_RELOC_TREE,
+           &root->state))
                return;
 
        if (!rc->merge_reloc_tree)
@@ -4752,7 +4756,8 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
        struct reloc_control *rc = root->fs_info->reloc_ctl;
        int ret;
 
-       if (!root->reloc_root || !rc)
+       if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state) ||
+           !root->reloc_root || !rc)
                return 0;
 
        rc = root->fs_info->reloc_ctl;