drbd: queue bitmap writeout more intelligently
authorLars Ellenberg <lars.ellenberg@linbit.com>
Thu, 20 Jan 2011 09:32:05 +0000 (10:32 +0100)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 10 Mar 2011 10:47:56 +0000 (11:47 +0100)
The "lazy writeout" of cleared bitmap pages happens during resync, and
should happen again once the resync finishes cleanly, or is aborted.

If resync finished cleanly, or was aborted because of peer disk
failure, we trigger the writeout from worker context in the after
state change work.

If resync was aborted because of connection failure, we should not
immediately trigger bitmap writeout, but rather postpone the
writeout to after the connection cleanup happened.  We now do it
in the receiver context from drbd_disconnect().

If resync was aborted because of local disk failure, well, there
is nothing to write to anymore.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_receiver.c

index 1caced08a73e9b6b3eb17764f64b30d4a2c6307c..e0be4077d564bf38886b68da764e63ceb3aa6647 100644 (file)
@@ -1593,8 +1593,18 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
        if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
                drbd_send_state(mdev);
 
-       if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED)
+       /* This triggers bitmap writeout of potentially still unwritten pages
+        * if the resync finished cleanly, or aborted because of peer disk
+        * failure.  Resync aborted because of connection failure does bitmap
+        * writeout from drbd_disconnect.
+        * For resync aborted because of local disk failure, we cannot do
+        * any bitmap writeout anymore.
+        */
+       if (os.conn > C_CONNECTED && ns.conn == C_CONNECTED &&
+           mdev->state.conn == C_CONNECTED && get_ldev(mdev)) {
                drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished");
+               put_ldev(mdev);
+       }
 
        /* free tl_hash if we Got thawed and are C_STANDALONE */
        if (ns.conn == C_STANDALONE && !is_susp(ns) && mdev->tl_hash)
index 3ccc6c33a330dda33dc2c828621c9847db189c95..432fe8f6b5d2647218f600ccbf8de688e840e431 100644 (file)
@@ -3811,6 +3811,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 
        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);
        }