rbd: avoid a deadlock on header_rwsem when flushing notifies
authorIlya Dryomov <idryomov@gmail.com>
Fri, 13 Mar 2020 10:20:51 +0000 (11:20 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 13 Apr 2020 06:55:49 +0000 (08:55 +0200)
commit0e4e1de5b63fa423b13593337a27fd2d2b0bcf77
tree8abbb9cb2d0db92749231abb3214c5b2699dd11c
parent8f3d9f354286745c751374f5f1fcafee6b3f3136
rbd: avoid a deadlock on header_rwsem when flushing notifies

rbd_unregister_watch() flushes notifies and therefore cannot be called
under header_rwsem because a header update notify takes header_rwsem to
synchronize with "rbd map".  If mapping an image fails after the watch
is established and a header update notify sneaks in, we deadlock when
erroring out from rbd_dev_image_probe().

Move watch registration and unregistration out of the critical section.
The only reason they were put there was to make header_rwsem management
slightly more obvious.

Fixes: 811c66887746 ("rbd: fix rbd map vs notify races")
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Jason Dillaman <dillaman@redhat.com>
drivers/block/rbd.c