summaryrefslogtreecommitdiff
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2010-12-15 08:59:11 +0100
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 11:43:19 +0100
commit19f843aa08e2d8f87a09b4c2edc43b00638423a8 (patch)
tree49919bd17ba7e03eb7cb76175910714d55704997 /drivers/block/drbd/drbd_main.c
parent95a0f10cddbf93ce89c175ac1c53dad2d20ad309 (diff)
downloadlwn-19f843aa08e2d8f87a09b4c2edc43b00638423a8.tar.gz
lwn-19f843aa08e2d8f87a09b4c2edc43b00638423a8.zip
drbd: bitmap keep track of changes vs on-disk bitmap
When we set or clear bits in a bitmap page, also set a flag in the page->private pointer. This allows us to skip writes of unchanged pages. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r--drivers/block/drbd/drbd_main.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 67fffad213ec..57ed7181742d 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1289,6 +1289,26 @@ static void abw_start_sync(struct drbd_conf *mdev, int rv)
}
}
+int drbd_bitmap_io_from_worker(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why)
+{
+ int rv;
+
+ D_ASSERT(current == mdev->worker.task);
+
+ /* open coded non-blocking drbd_suspend_io(mdev); */
+ set_bit(SUSPEND_IO, &mdev->flags);
+ if (!is_susp(mdev->state))
+ D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0);
+
+ drbd_bm_lock(mdev, why);
+ rv = io_fn(mdev);
+ drbd_bm_unlock(mdev);
+
+ drbd_resume_io(mdev);
+
+ return rv;
+}
+
/**
* after_state_ch() - Perform after state change actions that may sleep
* @mdev: DRBD device.
@@ -1404,7 +1424,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
/* D_DISKLESS Peer becomes secondary */
if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
- drbd_al_to_on_disk_bm(mdev);
+ drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, "demote diskless peer");
+ put_ldev(mdev);
+ }
+
+ if (os.role == R_PRIMARY && ns.role == R_SECONDARY && get_ldev(mdev)) {
+ drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, "demote");
put_ldev(mdev);
}