Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 213162
b: refs/heads/master
c: 9d28287
h: refs/heads/master
v: v3
  • Loading branch information
Lars Ellenberg authored and Philipp Reisner committed Oct 14, 2010
1 parent 58a22a0 commit 578c508
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f8488e1608b6e30e705460f8110888c645f7f9f
refs/heads/master: 9d282875d85ebc2b49362310677fc0dcd91b9db9
28 changes: 19 additions & 9 deletions trunk/drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1393,17 +1393,22 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
}

if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) {
int c = atomic_read(&mdev->local_cnt);

/* We must still be diskless,
* re-attach has to be serialized with this! */
if (mdev->state.disk != D_DISKLESS)
dev_err(DEV,
"ASSERT FAILED: disk is %s while going diskless\n",
drbd_disk_str(mdev->state.disk));

/* we cannot assert local_cnt == 0 here, as get_ldev_if_state
* will inc/dec it frequently. Since we became D_DISKLESS, no
* one has touched the protected members anymore, though, so we
* are safe to free them here. */
if (drbd_send_state(mdev))
dev_warn(DEV, "Notified peer that I detached my disk.\n");
else
dev_err(DEV, "Sending state for detach failed\n");

if (c != 0) {
dev_err(DEV, "Logic bug, local_cnt=%d, but should be 0\n", c);
wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
}
lc_destroy(mdev->resync);
mdev->resync = NULL;
lc_destroy(mdev->act_log);
Expand Down Expand Up @@ -3723,8 +3728,10 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused)
static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused)
{
D_ASSERT(mdev->state.disk == D_FAILED);
D_ASSERT(atomic_read(&mdev->local_cnt) == 0);

/* we cannot assert local_cnt == 0 here, as get_ldev_if_state will
* inc/dec it frequently. Once we are D_DISKLESS, no one will touch
* the protected members anymore, though, so in the after_state_ch work
* it will be safe to free them. */
drbd_force_state(mdev, NS(disk, D_DISKLESS));

clear_bit(GO_DISKLESS, &mdev->flags);
Expand All @@ -3735,7 +3742,10 @@ void drbd_go_diskless(struct drbd_conf *mdev)
{
D_ASSERT(mdev->state.disk == D_FAILED);
if (!test_and_set_bit(GO_DISKLESS, &mdev->flags))
drbd_queue_work_front(&mdev->data.work, &mdev->go_diskless);
drbd_queue_work(&mdev->data.work, &mdev->go_diskless);
/* don't drbd_queue_work_front,
* we need to serialize with the after_state_ch work
* of the -> D_FAILED transition. */
}

/**
Expand Down

0 comments on commit 578c508

Please sign in to comment.