aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2010-10-14 07:57:07 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 13:08:32 -0400
commit9d282875d85ebc2b49362310677fc0dcd91b9db9 (patch)
treebbbb183462f56b4b065e6dcc5e686587f90ce192 /drivers
parent0f8488e1608b6e30e705460f8110888c645f7f9f (diff)
drbd: drop wrong debug asserts, fix recently introduced race
commit 2372c38caadeaebc68a5ee190782c2a0df01edc3 drbd: fix for possible deadlock on IO error during resync introduced a new ASSERT, which turns out to be wrong. Drop it. Also serialize the state change to D_DISKLESS with the after state change work of the -> D_FAILED transition, don't open a new race. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/drbd/drbd_main.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f89b97466d07..342574f6d92e 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1393,17 +1393,22 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1393 } 1393 }
1394 1394
1395 if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) { 1395 if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) {
1396 int c = atomic_read(&mdev->local_cnt); 1396 /* We must still be diskless,
1397 1397 * re-attach has to be serialized with this! */
1398 if (mdev->state.disk != D_DISKLESS)
1399 dev_err(DEV,
1400 "ASSERT FAILED: disk is %s while going diskless\n",
1401 drbd_disk_str(mdev->state.disk));
1402
1403 /* we cannot assert local_cnt == 0 here, as get_ldev_if_state
1404 * will inc/dec it frequently. Since we became D_DISKLESS, no
1405 * one has touched the protected members anymore, though, so we
1406 * are safe to free them here. */
1398 if (drbd_send_state(mdev)) 1407 if (drbd_send_state(mdev))
1399 dev_warn(DEV, "Notified peer that I detached my disk.\n"); 1408 dev_warn(DEV, "Notified peer that I detached my disk.\n");
1400 else 1409 else
1401 dev_err(DEV, "Sending state for detach failed\n"); 1410 dev_err(DEV, "Sending state for detach failed\n");
1402 1411
1403 if (c != 0) {
1404 dev_err(DEV, "Logic bug, local_cnt=%d, but should be 0\n", c);
1405 wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
1406 }
1407 lc_destroy(mdev->resync); 1412 lc_destroy(mdev->resync);
1408 mdev->resync = NULL; 1413 mdev->resync = NULL;
1409 lc_destroy(mdev->act_log); 1414 lc_destroy(mdev->act_log);
@@ -3723,8 +3728,10 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
3723static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) 3728static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused)
3724{ 3729{
3725 D_ASSERT(mdev->state.disk == D_FAILED); 3730 D_ASSERT(mdev->state.disk == D_FAILED);
3726 D_ASSERT(atomic_read(&mdev->local_cnt) == 0); 3731 /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
3727 3732 * inc/dec it frequently. Once we are D_DISKLESS, no one will touch
3733 * the protected members anymore, though, so in the after_state_ch work
3734 * it will be safe to free them. */
3728 drbd_force_state(mdev, NS(disk, D_DISKLESS)); 3735 drbd_force_state(mdev, NS(disk, D_DISKLESS));
3729 3736
3730 clear_bit(GO_DISKLESS, &mdev->flags); 3737 clear_bit(GO_DISKLESS, &mdev->flags);
@@ -3735,7 +3742,10 @@ void drbd_go_diskless(struct drbd_conf *mdev)
3735{ 3742{
3736 D_ASSERT(mdev->state.disk == D_FAILED); 3743 D_ASSERT(mdev->state.disk == D_FAILED);
3737 if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) 3744 if (!test_and_set_bit(GO_DISKLESS, &mdev->flags))
3738 drbd_queue_work_front(&mdev->data.work, &mdev->go_diskless); 3745 drbd_queue_work(&mdev->data.work, &mdev->go_diskless);
3746 /* don't drbd_queue_work_front,
3747 * we need to serialize with the after_state_ch work
3748 * of the -> D_FAILED transition. */
3739} 3749}
3740 3750
3741/** 3751/**