aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2009-06-22 10:12:17 +0100
committerAlasdair G Kergon <agk@redhat.com>2009-06-22 10:12:17 +0100
commit32a926da5a16c01a8213331e5764472ce2f14a8d (patch)
treeedac1cef90e4754353a50fb948c4e34b4df8b5bc /include
parentdb8fef4fabe4a546ce74f80bff64fd43776e5912 (diff)
dm: always hold bdev reference
Fix a potential deadlock when creating multiple snapshots by holding a reference to struct block_device for the whole lifecycle of every dm device instead of obtaining it independently at each point it is needed. bdget_disk() was called while the device was being suspended, in dm_suspend(). However there could be other devices already suspended, for example when creating additional snapshots of a device. bdget_disk() can wait for IO and allocate memory resulting in waiting for the already-suspended device - deadlock. This patch changes the code so that it gets the reference to struct block_device when struct mapped_device is allocated and initialized in alloc_dev() where it is always OK to allocate memory or wait for I/O. It drops the reference when it is destroyed in free_dev(). Thus there is no call to bdget_disk() while any device is suspended. Previously unlock_fs() was called only if bdev was held. Now it is called unconditionally, but the superfluous calls are harmless because it returns immediately if the filesystem was not previously frozen. This patch also now allows the device size to be changed in a noflush suspend because the bdev is held. This has no adverse effect. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'include')
0 files changed, 0 insertions, 0 deletions