aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2010-06-24 10:24:25 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2010-10-14 09:09:09 -0400
commit6709893059105d7859ae772af70c7db5bbab7de0 (patch)
tree939d177fc3f70970d46442ee7953b1467d6aabc5 /drivers/block/drbd/drbd_main.c
parentf70b3511599c49a3dc20ae349d6cdc5af47659df (diff)
drbd: Make sure tl_restart(, resend) can not get called multiple times for a new connection
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.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 8d14635e7faf..c6658f5a5c1c 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1209,6 +1209,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1209 union drbd_state ns, enum chg_state_flags flags) 1209 union drbd_state ns, enum chg_state_flags flags)
1210{ 1210{
1211 enum drbd_fencing_p fp; 1211 enum drbd_fencing_p fp;
1212 enum drbd_req_event what = nothing;
1212 1213
1213 if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) { 1214 if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) {
1214 clear_bit(CRASHED_PRIMARY, &mdev->flags); 1215 clear_bit(CRASHED_PRIMARY, &mdev->flags);
@@ -1234,21 +1235,14 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1234 1235
1235 if (os.susp && ns.susp && mdev->sync_conf.on_no_data == OND_SUSPEND_IO) { 1236 if (os.susp && ns.susp && mdev->sync_conf.on_no_data == OND_SUSPEND_IO) {
1236 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) { 1237 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
1237 if (ns.conn == C_CONNECTED) { 1238 if (ns.conn == C_CONNECTED)
1238 spin_lock_irq(&mdev->req_lock); 1239 what = resend;
1239 _tl_restart(mdev, resend); 1240 else /* ns.conn > C_CONNECTED */
1240 _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
1241 spin_unlock_irq(&mdev->req_lock);
1242 } else /* ns.conn > C_CONNECTED */
1243 dev_err(DEV, "Unexpected Resynd going on!\n"); 1241 dev_err(DEV, "Unexpected Resynd going on!\n");
1244 } 1242 }
1245 1243
1246 if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING) { 1244 if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING)
1247 spin_lock_irq(&mdev->req_lock); 1245 what = restart_frozen_disk_io;
1248 _tl_restart(mdev, restart_frozen_disk_io);
1249 _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
1250 spin_unlock_irq(&mdev->req_lock);
1251 }
1252 } 1246 }
1253 1247
1254 if (fp == FP_STONITH && ns.susp) { 1248 if (fp == FP_STONITH && ns.susp) {
@@ -1267,12 +1261,17 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1267 /* case2: The connection was established again: */ 1261 /* case2: The connection was established again: */
1268 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) { 1262 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
1269 clear_bit(NEW_CUR_UUID, &mdev->flags); 1263 clear_bit(NEW_CUR_UUID, &mdev->flags);
1270 spin_lock_irq(&mdev->req_lock); 1264 what = resend;
1271 _tl_restart(mdev, resend);
1272 _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
1273 spin_unlock_irq(&mdev->req_lock);
1274 } 1265 }
1275 } 1266 }
1267
1268 if (what != nothing) {
1269 spin_lock_irq(&mdev->req_lock);
1270 _tl_restart(mdev, what);
1271 _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
1272 spin_unlock_irq(&mdev->req_lock);
1273 }
1274
1276 /* Do not change the order of the if above and the two below... */ 1275 /* Do not change the order of the if above and the two below... */
1277 if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) { /* attach on the peer */ 1276 if (os.pdsk == D_DISKLESS && ns.pdsk > D_DISKLESS) { /* attach on the peer */
1278 drbd_send_uuids(mdev); 1277 drbd_send_uuids(mdev);