diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2015-06-08 15:18:45 +0200 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-11-25 17:22:03 +0100 |
commit | 5f7c01249bea67c32a1a1551a8f2fe0b8b801ab4 (patch) | |
tree | 369efade0df17d0170e1dcade7b9043e559f372a /drivers/block/drbd/drbd_int.h | |
parent | drbd: separate out __al_write_transaction helper function (diff) | |
download | linux-5f7c01249bea67c32a1a1551a8f2fe0b8b801ab4.tar.xz linux-5f7c01249bea67c32a1a1551a8f2fe0b8b801ab4.zip |
drbd: avoid potential deadlock during handshake
During handshake communication, we also reconsider our device size,
using drbd_determine_dev_size(). Just in case we need to change the
offsets or layout of our on-disk metadata, we lock out application
and other meta data IO, and wait for the activity log to be "idle"
(no more referenced extents).
If this handshake happens just after a connection loss, with a fencing
policy of "resource-and-stonith", we have frozen IO.
If, additionally, the activity log was "starving" (too many incoming
random writes at that point in time), it won't become idle, ever,
because of the frozen IO, and this would be a lockup of the receiver
thread, and consquentially of DRBD.
Previous logic (re-)initialized with a special "empty" transaction
block, which required the activity log to fully drain first.
Instead, write out some standard activity log transactions.
Using lc_try_lock_for_transaction() instead of lc_try_lock() does not
care about pending activity log references, avoiding the potential
deadlock.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block/drbd/drbd_int.h')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index df3d89d5777a..b6844feb9f9b 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1667,7 +1667,7 @@ extern int __drbd_change_sync(struct drbd_device *device, sector_t sector, int s #define drbd_rs_failed_io(device, sector, size) \ __drbd_change_sync(device, sector, size, RECORD_RS_FAILED) extern void drbd_al_shrink(struct drbd_device *device); -extern int drbd_initialize_al(struct drbd_device *, void *); +extern int drbd_al_initialize(struct drbd_device *, void *); /* drbd_nl.c */ /* state info broadcast */ |