diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2012-08-28 13:33:35 +0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-09 17:08:23 +0400 |
commit | 797020117761eee21ef284cea90c51c690fca169 (patch) | |
tree | f631b73335e5a2211525a692ac57901d4c48b126 | |
parent | 07fc96197aec46f7ad4f08a4b2a1ea426112e24d (diff) | |
download | linux-797020117761eee21ef284cea90c51c690fca169.tar.xz |
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 <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_state.c | 29 |
1 files changed, 23 insertions, 6 deletions
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. |