From 797020117761eee21ef284cea90c51c690fca169 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 28 Aug 2012 11:33:35 +0200 Subject: drbd: Fix the way the STATE_SENT bit is cleared With merging the commit 'drbd: Delay/reject other state changes while establishing a connection' the condition check for clearing the flag was wrong. Move the bit clearing to the __drbd_set_state() function in order to have it already cleared for the other parts of the function. I.e. clearing the susp_fen in the after_state_ch() function. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_state.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers/block/drbd') diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 9ae40c96c1be..a16278cde3db 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -186,6 +186,24 @@ enum drbd_conns conn_lowest_conn(struct drbd_tconn *tconn) return conn; } +static bool no_peer_wf_report_params(struct drbd_tconn *tconn) +{ + struct drbd_conf *mdev; + int vnr; + bool rv = true; + + rcu_read_lock(); + idr_for_each_entry(&tconn->volumes, mdev, vnr) + if (mdev->state.conn == C_WF_REPORT_PARAMS) { + rv = false; + break; + } + rcu_read_unlock(); + + return rv; +} + + /** * cl_wide_st_chg() - true if the state change is a cluster wide one * @mdev: DRBD device. @@ -971,6 +989,11 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING) drbd_print_uuids(mdev, "attached to UUIDs"); + /* Wake up role changes, that were delayed because of connection establishing */ + if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS && + no_peer_wf_report_params(mdev->tconn)) + clear_bit(STATE_SENT, &mdev->tconn->flags); + wake_up(&mdev->misc_wait); wake_up(&mdev->state_wait); wake_up(&mdev->tconn->ping_wait); @@ -1457,12 +1480,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, && verify_can_do_stop_sector(mdev)) drbd_send_state(mdev, ns); - /* Wake up role changes, that were delayed because of connection establishing */ - if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS) { - if (test_and_clear_bit(STATE_SENT, &mdev->tconn->flags)) - wake_up(&mdev->state_wait); - } - /* This triggers bitmap writeout of potentially still unwritten pages * if the resync finished cleanly, or aborted because of peer disk * failure, or because of connection loss. -- cgit v1.2.2