drbd: Fix IO resuming after connection was established while executing the fence handler

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 755425a..60dde03 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -1204,6 +1204,28 @@
 		}
 	}
 
+	if (ns.susp_fen) {
+		struct drbd_tconn *tconn = mdev->tconn;
+
+		spin_lock_irq(&tconn->req_lock);
+		if (tconn->susp_fen && conn_lowest_conn(tconn) >= C_CONNECTED) {
+			/* case2: The connection was established again: */
+			struct drbd_conf *odev;
+			int vnr;
+
+			rcu_read_lock();
+			idr_for_each_entry(&tconn->volumes, odev, vnr)
+				clear_bit(NEW_CUR_UUID, &odev->flags);
+			rcu_read_unlock();
+			_tl_restart(tconn, RESEND);
+			_conn_request_state(tconn,
+					    (union drbd_state) { { .susp_fen = 1 } },
+					    (union drbd_state) { { .susp_fen = 0 } },
+					    CS_VERBOSE);
+		}
+		spin_unlock_irq(&tconn->req_lock);
+	}
+
 	/* Became sync source.  With protocol >= 96, we still need to send out
 	 * the sync uuid now. Need to do that before any drbd_send_state, or
 	 * the other side may go "paused sync" before receiving the sync uuids,
@@ -1475,7 +1497,6 @@
 	struct drbd_tconn *tconn = w->tconn;
 	enum drbd_conns oc = acscw->oc;
 	union drbd_state ns_max = acscw->ns_max;
-	union drbd_state ns_min = acscw->ns_min;
 	struct drbd_conf *mdev;
 	int vnr;
 
@@ -1519,20 +1540,6 @@
 					    CS_VERBOSE);
 			spin_unlock_irq(&tconn->req_lock);
 		}
-		/* case2: The connection was established again: */
-		if (ns_min.conn >= C_CONNECTED) {
-			rcu_read_lock();
-			idr_for_each_entry(&tconn->volumes, mdev, vnr)
-				clear_bit(NEW_CUR_UUID, &mdev->flags);
-			rcu_read_unlock();
-			spin_lock_irq(&tconn->req_lock);
-			_tl_restart(tconn, RESEND);
-			_conn_request_state(tconn,
-					    (union drbd_state) { { .susp_fen = 1 } },
-					    (union drbd_state) { { .susp_fen = 0 } },
-					    CS_VERBOSE);
-			spin_unlock_irq(&tconn->req_lock);
-		}
 	}
 	kref_put(&tconn->kref, &conn_destroy);
 	return 0;