aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2011-01-21 04:56:44 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2011-03-10 05:48:02 -0500
commit20ceb2b22edaf51e59e76087efdc71a16a2858de (patch)
treea4f267242725bac2a915e879a6b6ac259218c5fa /drivers/block/drbd/drbd_main.c
parent62b0da3a244ac33d25a77861ef1cc0080103f2ff (diff)
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>
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r--drivers/block/drbd/drbd_main.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index b68332a0e73e..a9e9b496e73b 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1320,7 +1320,9 @@ static void abw_start_sync(struct drbd_conf *mdev, int rv)
1320 } 1320 }
1321} 1321}
1322 1322
1323int drbd_bitmap_io_from_worker(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why) 1323int drbd_bitmap_io_from_worker(struct drbd_conf *mdev,
1324 int (*io_fn)(struct drbd_conf *),
1325 char *why, enum bm_flag flags)
1324{ 1326{
1325 int rv; 1327 int rv;
1326 1328
@@ -1328,10 +1330,8 @@ int drbd_bitmap_io_from_worker(struct drbd_conf *mdev, int (*io_fn)(struct drbd_
1328 1330
1329 /* open coded non-blocking drbd_suspend_io(mdev); */ 1331 /* open coded non-blocking drbd_suspend_io(mdev); */
1330 set_bit(SUSPEND_IO, &mdev->flags); 1332 set_bit(SUSPEND_IO, &mdev->flags);
1331 if (!is_susp(mdev->state))
1332 D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0);
1333 1333
1334 drbd_bm_lock(mdev, why); 1334 drbd_bm_lock(mdev, why, flags);
1335 rv = io_fn(mdev); 1335 rv = io_fn(mdev);
1336 drbd_bm_unlock(mdev); 1336 drbd_bm_unlock(mdev);
1337 1337
@@ -1438,7 +1438,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1438 if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S && 1438 if (os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S &&
1439 mdev->state.conn == C_WF_BITMAP_S) 1439 mdev->state.conn == C_WF_BITMAP_S)
1440 drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL, 1440 drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL,
1441 "send_bitmap (WFBitMapS)"); 1441 "send_bitmap (WFBitMapS)",
1442 BM_LOCKED_TEST_ALLOWED);
1442 1443
1443 /* Lost contact to peer's copy of the data */ 1444 /* Lost contact to peer's copy of the data */
1444 if ((os.pdsk >= D_INCONSISTENT && 1445 if ((os.pdsk >= D_INCONSISTENT &&
@@ -1469,7 +1470,11 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1469 1470
1470 /* D_DISKLESS Peer becomes secondary */ 1471 /* D_DISKLESS Peer becomes secondary */
1471 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) 1472 if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY)
1472 drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, "demote diskless peer"); 1473 /* We may still be Primary ourselves.
1474 * No harm done if the bitmap still changes,
1475 * redirtied pages will follow later. */
1476 drbd_bitmap_io_from_worker(mdev, &drbd_bm_write,
1477 "demote diskless peer", BM_LOCKED_SET_ALLOWED);
1473 put_ldev(mdev); 1478 put_ldev(mdev);
1474 } 1479 }
1475 1480
@@ -1478,7 +1483,10 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1478 * if there is a resync going on still */ 1483 * if there is a resync going on still */
1479 if (os.role == R_PRIMARY && ns.role == R_SECONDARY && 1484 if (os.role == R_PRIMARY && ns.role == R_SECONDARY &&
1480 mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) { 1485 mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) {
1481 drbd_bitmap_io_from_worker(mdev, &drbd_bm_write, "demote"); 1486 /* No changes to the bitmap expected this time, so assert that,
1487 * even though no harm was done if it did change. */
1488 drbd_bitmap_io_from_worker(mdev, &drbd_bm_write,
1489 "demote", BM_LOCKED_TEST_ALLOWED);
1482 put_ldev(mdev); 1490 put_ldev(mdev);
1483 } 1491 }
1484 1492
@@ -1512,12 +1520,17 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1512 /* We are in the progress to start a full sync... */ 1520 /* We are in the progress to start a full sync... */
1513 if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) || 1521 if ((os.conn != C_STARTING_SYNC_T && ns.conn == C_STARTING_SYNC_T) ||
1514 (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S)) 1522 (os.conn != C_STARTING_SYNC_S && ns.conn == C_STARTING_SYNC_S))
1515 drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, &abw_start_sync, "set_n_write from StartingSync"); 1523 /* no other bitmap changes expected during this phase */
1524 drbd_queue_bitmap_io(mdev,
1525 &drbd_bmio_set_n_write, &abw_start_sync,
1526 "set_n_write from StartingSync", BM_LOCKED_TEST_ALLOWED);
1516 1527
1517 /* We are invalidating our self... */ 1528 /* We are invalidating our self... */
1518 if (os.conn < C_CONNECTED && ns.conn < C_CONNECTED && 1529 if (os.conn < C_CONNECTED && ns.conn < C_CONNECTED &&
1519 os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) 1530 os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT)
1520 drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); 1531 /* other bitmap operation expected during this phase */
1532 drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL,
1533 "set_n_write from invalidate", BM_LOCKED_MASK);
1521 1534
1522 /* first half of local IO error, failure to attach, 1535 /* first half of local IO error, failure to attach,
1523 * or administrative detach */ 1536 * or administrative detach */
@@ -1599,14 +1612,14 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1599 1612
1600 /* This triggers bitmap writeout of potentially still unwritten pages 1613 /* This triggers bitmap writeout of potentially still unwritten pages
1601 * if the resync finished cleanly, or aborted because of peer disk 1614 * if the resync finished cleanly, or aborted because of peer disk
1602 * failure. Resync aborted because of connection failure does bitmap 1615 * failure, or because of connection loss.
1603 * writeout from drbd_disconnect.
1604 * For resync aborted because of local disk failure, we cannot do 1616 * For resync aborted because of local disk failure, we cannot do
1605 * any bitmap writeout anymore. 1617 * any bitmap writeout anymore.
1618 * No harm done if some bits change during this phase.
1606 */ 1619 */
1607 if (os.conn > C_CONNECTED && ns.conn == C_CONNECTED && 1620 if (os.conn > C_CONNECTED && ns.conn <= C_CONNECTED && get_ldev(mdev)) {
1608 mdev->state.conn == C_CONNECTED && get_ldev(mdev)) { 1621 drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL,
1609 drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); 1622 "write from resync_finished", BM_LOCKED_SET_ALLOWED);
1610 put_ldev(mdev); 1623 put_ldev(mdev);
1611 } 1624 }
1612 1625
@@ -3929,7 +3942,7 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
3929 D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0); 3942 D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0);
3930 3943
3931 if (get_ldev(mdev)) { 3944 if (get_ldev(mdev)) {
3932 drbd_bm_lock(mdev, work->why); 3945 drbd_bm_lock(mdev, work->why, work->flags);
3933 rv = work->io_fn(mdev); 3946 rv = work->io_fn(mdev);
3934 drbd_bm_unlock(mdev); 3947 drbd_bm_unlock(mdev);
3935 put_ldev(mdev); 3948 put_ldev(mdev);
@@ -3944,6 +3957,7 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
3944 3957
3945 clear_bit(BITMAP_IO_QUEUED, &mdev->flags); 3958 clear_bit(BITMAP_IO_QUEUED, &mdev->flags);
3946 work->why = NULL; 3959 work->why = NULL;
3960 work->flags = 0;
3947 3961
3948 return 1; 3962 return 1;
3949} 3963}
@@ -3998,7 +4012,7 @@ void drbd_go_diskless(struct drbd_conf *mdev)
3998void drbd_queue_bitmap_io(struct drbd_conf *mdev, 4012void drbd_queue_bitmap_io(struct drbd_conf *mdev,
3999 int (*io_fn)(struct drbd_conf *), 4013 int (*io_fn)(struct drbd_conf *),
4000 void (*done)(struct drbd_conf *, int), 4014 void (*done)(struct drbd_conf *, int),
4001 char *why) 4015 char *why, enum bm_flag flags)
4002{ 4016{
4003 D_ASSERT(current == mdev->worker.task); 4017 D_ASSERT(current == mdev->worker.task);
4004 4018
@@ -4012,6 +4026,7 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev,
4012 mdev->bm_io_work.io_fn = io_fn; 4026 mdev->bm_io_work.io_fn = io_fn;
4013 mdev->bm_io_work.done = done; 4027 mdev->bm_io_work.done = done;
4014 mdev->bm_io_work.why = why; 4028 mdev->bm_io_work.why = why;
4029 mdev->bm_io_work.flags = flags;
4015 4030
4016 spin_lock_irq(&mdev->req_lock); 4031 spin_lock_irq(&mdev->req_lock);
4017 set_bit(BITMAP_IO, &mdev->flags); 4032 set_bit(BITMAP_IO, &mdev->flags);
@@ -4031,19 +4046,22 @@ void drbd_queue_bitmap_io(struct drbd_conf *mdev,
4031 * freezes application IO while that the actual IO operations runs. This 4046 * freezes application IO while that the actual IO operations runs. This
4032 * functions MAY NOT be called from worker context. 4047 * functions MAY NOT be called from worker context.
4033 */ 4048 */
4034int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why) 4049int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *),
4050 char *why, enum bm_flag flags)
4035{ 4051{
4036 int rv; 4052 int rv;
4037 4053
4038 D_ASSERT(current != mdev->worker.task); 4054 D_ASSERT(current != mdev->worker.task);
4039 4055
4040 drbd_suspend_io(mdev); 4056 if ((flags & BM_LOCKED_SET_ALLOWED) == 0)
4057 drbd_suspend_io(mdev);
4041 4058
4042 drbd_bm_lock(mdev, why); 4059 drbd_bm_lock(mdev, why, flags);
4043 rv = io_fn(mdev); 4060 rv = io_fn(mdev);
4044 drbd_bm_unlock(mdev); 4061 drbd_bm_unlock(mdev);
4045 4062
4046 drbd_resume_io(mdev); 4063 if ((flags & BM_LOCKED_SET_ALLOWED) == 0)
4064 drbd_resume_io(mdev);
4047 4065
4048 return rv; 4066 return rv;
4049} 4067}