aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
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)
1289 } 1289 }
1290} 1290}
1291 1291
1292int drbd_bitmap_io_from_worker(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why)
1293{
1294 int rv;
1295
1296 D_ASSERT(current == mdev->worker.task);
1297
1298 /* open coded non-blocking drbd_suspend_io(mdev); */
1299 set_bit(SUSPEND_IO, &mdev->flags);
1300 if (!is_susp(mdev->state))
1301 D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0);
1302
1303 drbd_bm_lock(mdev, why);
1304 rv = io_fn(mdev);
1305 drbd_bm_unlock(mdev);
1306
1307 drbd_resume_io(mdev);
1308
1309 return rv;
1310}
1311
1292/** 1312/**
1293 * after_state_ch() - Perform after state change actions that may sleep 1313 * after_state_ch() - Perform after state change actions that may sleep
1294 * @mdev: DRBD device. 1314 * @mdev: DRBD device.
@@ -1404,7 +1424,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1404 1424
1405 /* D_DISKLESS Peer becomes secondary */ 1425 /* D_DISKLESS Peer becomes secondary */
1406 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) 1426 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
1407 drbd_al_to_on_disk_bm(mdev); 1427 drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, "demote diskless peer");
1428 put_ldev(mdev);
1429 }
1430
1431 if (os.role == R_PRIMARY && ns.role == R_SECONDARY && get_ldev(mdev)) {
1432 drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, "demote");
1408 put_ldev(mdev); 1433 put_ldev(mdev);
1409 } 1434 }
1410 1435