drbd: describe bitmap locking for bulk operation in finer detail
Now that we do no longer in-place endian-swap the bitmap, we allow
selected bitmap operations (testing bits, sometimes even settting bits)
during some bulk operations.
This caused us to hit a lot of FIXME asserts similar to
FIXME asender in drbd_bm_count_bits,
bitmap locked for 'write from resync_finished' by worker
Which now is nonsense: looking at the bitmap is perfectly legal
as long as it is not being resized.
This cosmetic patch defines some flags to describe expectations in finer
detail, so the asserts in e.g. bm_change_bits_to() can be skipped if
appropriate.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index e5686a8..e13134f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2599,7 +2599,8 @@
if (abs(hg) >= 2) {
dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
- if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake"))
+ if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake",
+ BM_LOCKED_SET_ALLOWED))
return C_MASK;
}
@@ -3053,7 +3054,8 @@
if (skip_initial_sync) {
dev_info(DEV, "Accepted new current UUID, preparing to skip initial sync\n");
drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write,
- "clear_n_write from receive_uuids");
+ "clear_n_write from receive_uuids",
+ BM_LOCKED_TEST_ALLOWED);
_drbd_uuid_set(mdev, UI_CURRENT, p_uuid[UI_CURRENT]);
_drbd_uuid_set(mdev, UI_BITMAP, 0);
_drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE),
@@ -3494,7 +3496,9 @@
int ok = false;
struct p_header80 *h = &mdev->data.rbuf.header.h80;
- /* drbd_bm_lock(mdev, "receive bitmap"); By intention no bm_lock */
+ drbd_bm_lock(mdev, "receive bitmap", BM_LOCKED_SET_ALLOWED);
+ /* you are supposed to send additional out-of-sync information
+ * if you actually set bits during this phase */
/* maybe we should use some per thread scratch page,
* and allocate that during initial device creation? */
@@ -3568,7 +3572,7 @@
ok = true;
out:
- /* drbd_bm_unlock(mdev); by intention no lock */
+ drbd_bm_unlock(mdev);
if (ok && mdev->state.conn == C_WF_BITMAP_S)
drbd_start_resync(mdev, C_SYNC_SOURCE);
free_page((unsigned long) buffer);
@@ -3817,7 +3821,6 @@
fp = FP_DONT_CARE;
if (get_ldev(mdev)) {
- drbd_bitmap_io(mdev, &drbd_bm_write, "write from disconnect");
fp = mdev->ldev->dc.fencing;
put_ldev(mdev);
}
@@ -3846,6 +3849,10 @@
drbd_request_state(mdev, NS(conn, C_STANDALONE));
}
+ /* serialize with bitmap writeout triggered by the state change,
+ * if any. */
+ wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
+
/* tcp_close and release of sendpage pages can be deferred. I don't
* want to use SO_LINGER, because apparently it can be deferred for
* more than 20 seconds (longest time I checked).