Btrfs: fix NULL pointer crash when running balance and scrub concurrently
While running balance, scrub, fsstress concurrently we hit the
following kernel crash:
[56561.448845] BTRFS info (device sde): relocating block group
11005853696 flags 132
[56561.524077] BUG: unable to handle kernel NULL pointer dereference at
0000000000000078
[56561.524237] IP: [<
ffffffffa038956d>] scrub_chunk.isra.12+0xdd/0x130 [btrfs]
[56561.524297] PGD
9be28067 PUD
7f3dd067 PMD 0
[56561.524325] Oops: 0000 [#1] SMP
[....]
[56561.527237] Call Trace:
[56561.527309] [<
ffffffffa038980e>] scrub_enumerate_chunks+0x24e/0x490 [btrfs]
[56561.527392] [<
ffffffff810abe00>] ? abort_exclusive_wait+0x50/0xb0
[56561.527476] [<
ffffffffa038add4>] btrfs_scrub_dev+0x1a4/0x530 [btrfs]
[56561.527561] [<
ffffffffa0368107>] btrfs_ioctl+0x13f7/0x2a90 [btrfs]
[56561.527639] [<
ffffffff811c82f0>] do_vfs_ioctl+0x2e0/0x4c0
[56561.527712] [<
ffffffff8109c384>] ? vtime_account_user+0x54/0x60
[56561.527788] [<
ffffffff810f768c>] ? __audit_syscall_entry+0x9c/0xf0
[56561.527870] [<
ffffffff811c8551>] SyS_ioctl+0x81/0xa0
[56561.527941] [<
ffffffff815707f7>] tracesys+0xdd/0xe2
[...]
[56561.528304] RIP [<
ffffffffa038956d>] scrub_chunk.isra.12+0xdd/0x130 [btrfs]
[56561.528395] RSP <
ffff88004c0f5be8>
[56561.528454] CR2:
0000000000000078
This is because in btrfs_relocate_chunk(), we will free @bdev directly while
scrub may still hold extent mapping, and may access freed memory.
Fix this problem by wrapping freeing @bdev work into free_extent_map() which
is based on reference count.
Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>