Messages in this thread | | | Date | Wed, 2 Aug 2023 14:53:14 +0800 | Subject | Re: [syzbot] [btrfs?] kernel BUG in prepare_to_merge | From | Qu Wenruo <> |
| |
On 2023/8/1 23:26, Christoph Hellwig wrote: > In the meantime I've also reproduced it with just > "btrfs: fix the btrfs_get_global_root return value", but it took > a rather long time. > > After wading through the code my suspicion is that before this fix > the ERR_PTR return made that for those cases btrfs_get_root_ref and > btrfs_get_fs_root_commit_root don't actually do the > btrfs_lookup_fs_root. Although that seemed unintentional as far > as I can tell it might have prevented some additional problems > with whatever syzcaller is fuzzing here. Not sure if anyone who > knows this code has any good idea where to start looking? >
I'm also looking into the case, the weird part seems to be we're getting some race between qgroup tree creation and relocation.
More rounds of syzbot testing shows it's not on-disk data corruption, but runtime corruption lead to the invalid reloc tree key.
Normally if we're relocating tree 8 (quota tree), we should get fs_info->quota_root, and it should not has ROOT_SHAREABLE flag, thus we just go COW the involved quota tree block.
But by somehow, if the quota tree is created by btrfs_init_fs_root() it would has the ROOT_SHAREABLE flag and leads to the incorrect reloc tree creation.
My current guess is, some race like this:
Thread A | Thread B ---------------------------------+------------------------------ btrfs_quota_enable() | | | btrfs_get_root_ref() | | |- btrfs_get_global_root() | | | Returned NULL | | |- btrfs_lookup_fs_root() | | | Returned NULL |- btrfs_create_tree() | | | Now quota root item is | | | inserted | |- btrfs_read_tree_root() | | | Got the newly inserted quota root | | |- btrfs_init_fs_root() | | | Set ROOT_SHAREABLE flag
By this, with a relocation and quota enabling, we create a race that we can get a quota root with ROOT_SHAREABLE set, and lead to the problem.
Personally speaking, I don't have a particularly good idea on how to fix it.
We may skip any non-subvolume related trees in btrfs_init_fs_root(), but that doesn't seem correct to me.
Any good ideas on this?
Thanks, Qu
| |