dm: avoid _hash_lock deadlock
Fix a reported deadlock if there are still unprocessed multipath events
on a device that is being removed.
_hash_lock is held during dev_remove while trying to send the
outstanding events. Sending the events requests the _hash_lock
again in dm_copy_name_and_uuid.
This patch introduces a separate lock around regions that modify the
link to the hash table (dm_set_mdptr) or the name or uuid so that
dm_copy_name_and_uuid no longer needs _hash_lock.
Additionally, dm_copy_name_and_uuid can only be called if md exists
so we can drop the dm_get() and dm_put() which can lead to a BUG()
while md is being freed.
The deadlock:
#0 [
ffff8106298dfb48] schedule at
ffffffff80063035
#1 [
ffff8106298dfc20] __down_read at
ffffffff8006475d
#2 [
ffff8106298dfc60] dm_copy_name_and_uuid at
ffffffff8824f740
#3 [
ffff8106298dfc90] dm_send_uevents at
ffffffff88252685
#4 [
ffff8106298dfcd0] event_callback at
ffffffff8824c678
#5 [
ffff8106298dfd00] dm_table_event at
ffffffff8824dd01
#6 [
ffff8106298dfd10] __hash_remove at
ffffffff882507ad
#7 [
ffff8106298dfd30] dev_remove at
ffffffff88250865
#8 [
ffff8106298dfd60] ctl_ioctl at
ffffffff88250d80
#9 [
ffff8106298dfee0] do_ioctl at
ffffffff800418c4
#10 [
ffff8106298dff00] vfs_ioctl at
ffffffff8002fab9
#11 [
ffff8106298dff40] sys_ioctl at
ffffffff8004bdaf
#12 [
ffff8106298dff80] tracesys at
ffffffff8005d28d (via system_call)
Cc: stable@kernel.org
Reported-by: guy keren <choo@actcom.co.il>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>