aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r--drivers/block/drbd/drbd_main.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 04c305d36f8e..4f33714fb3cd 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -654,7 +654,7 @@ static void print_st(struct drbd_conf *mdev, char *name, union drbd_state ns)
654 drbd_role_str(ns.peer), 654 drbd_role_str(ns.peer),
655 drbd_disk_str(ns.disk), 655 drbd_disk_str(ns.disk),
656 drbd_disk_str(ns.pdsk), 656 drbd_disk_str(ns.pdsk),
657 ns.susp ? 's' : 'r', 657 is_susp(ns) ? 's' : 'r',
658 ns.aftr_isp ? 'a' : '-', 658 ns.aftr_isp ? 'a' : '-',
659 ns.peer_isp ? 'p' : '-', 659 ns.peer_isp ? 'p' : '-',
660 ns.user_isp ? 'u' : '-' 660 ns.user_isp ? 'u' : '-'
@@ -925,12 +925,12 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state
925 if (fp == FP_STONITH && 925 if (fp == FP_STONITH &&
926 (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) && 926 (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
927 !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED)) 927 !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
928 ns.susp = 1; /* Suspend IO while fence-peer handler runs (peer lost) */ 928 ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */
929 929
930 if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO && 930 if (mdev->sync_conf.on_no_data == OND_SUSPEND_IO &&
931 (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) && 931 (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
932 !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE)) 932 !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
933 ns.susp = 1; /* Suspend IO while no data available (no accessible data available) */ 933 ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */
934 934
935 if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { 935 if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
936 if (ns.conn == C_SYNC_SOURCE) 936 if (ns.conn == C_SYNC_SOURCE)
@@ -1030,7 +1030,10 @@ int __drbd_set_state(struct drbd_conf *mdev,
1030 PSC(conn); 1030 PSC(conn);
1031 PSC(disk); 1031 PSC(disk);
1032 PSC(pdsk); 1032 PSC(pdsk);
1033 PSC(susp); 1033 if (is_susp(ns) != is_susp(os))
1034 pbp += sprintf(pbp, "susp( %s -> %s ) ",
1035 drbd_susp_str(is_susp(os)),
1036 drbd_susp_str(is_susp(ns)));
1034 PSC(aftr_isp); 1037 PSC(aftr_isp);
1035 PSC(peer_isp); 1038 PSC(peer_isp);
1036 PSC(user_isp); 1039 PSC(user_isp);
@@ -1218,6 +1221,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1218{ 1221{
1219 enum drbd_fencing_p fp; 1222 enum drbd_fencing_p fp;
1220 enum drbd_req_event what = nothing; 1223 enum drbd_req_event what = nothing;
1224 union drbd_state nsm = (union drbd_state){ .i = -1 };
1221 1225
1222 if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) { 1226 if (os.conn != C_CONNECTED && ns.conn == C_CONNECTED) {
1223 clear_bit(CRASHED_PRIMARY, &mdev->flags); 1227 clear_bit(CRASHED_PRIMARY, &mdev->flags);
@@ -1241,19 +1245,21 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1241 /* Here we have the actions that are performed after a 1245 /* Here we have the actions that are performed after a
1242 state change. This function might sleep */ 1246 state change. This function might sleep */
1243 1247
1244 if (os.susp && ns.susp && mdev->sync_conf.on_no_data == OND_SUSPEND_IO) { 1248 nsm.i = -1;
1249 if (ns.susp_nod) {
1245 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) { 1250 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
1246 if (ns.conn == C_CONNECTED) 1251 if (ns.conn == C_CONNECTED)
1247 what = resend; 1252 what = resend, nsm.susp_nod = 0;
1248 else /* ns.conn > C_CONNECTED */ 1253 else /* ns.conn > C_CONNECTED */
1249 dev_err(DEV, "Unexpected Resynd going on!\n"); 1254 dev_err(DEV, "Unexpected Resynd going on!\n");
1250 } 1255 }
1251 1256
1252 if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING) 1257 if (os.disk == D_ATTACHING && ns.disk > D_ATTACHING)
1253 what = restart_frozen_disk_io; 1258 what = restart_frozen_disk_io, nsm.susp_nod = 0;
1259
1254 } 1260 }
1255 1261
1256 if (fp == FP_STONITH && ns.susp) { 1262 if (ns.susp_fen) {
1257 /* case1: The outdate peer handler is successful: */ 1263 /* case1: The outdate peer handler is successful: */
1258 if (os.pdsk > D_OUTDATED && ns.pdsk <= D_OUTDATED) { 1264 if (os.pdsk > D_OUTDATED && ns.pdsk <= D_OUTDATED) {
1259 tl_clear(mdev); 1265 tl_clear(mdev);
@@ -1263,20 +1269,22 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1263 drbd_md_sync(mdev); 1269 drbd_md_sync(mdev);
1264 } 1270 }
1265 spin_lock_irq(&mdev->req_lock); 1271 spin_lock_irq(&mdev->req_lock);
1266 _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL); 1272 _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);
1267 spin_unlock_irq(&mdev->req_lock); 1273 spin_unlock_irq(&mdev->req_lock);
1268 } 1274 }
1269 /* case2: The connection was established again: */ 1275 /* case2: The connection was established again: */
1270 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) { 1276 if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
1271 clear_bit(NEW_CUR_UUID, &mdev->flags); 1277 clear_bit(NEW_CUR_UUID, &mdev->flags);
1272 what = resend; 1278 what = resend;
1279 nsm.susp_fen = 0;
1273 } 1280 }
1274 } 1281 }
1275 1282
1276 if (what != nothing) { 1283 if (what != nothing) {
1277 spin_lock_irq(&mdev->req_lock); 1284 spin_lock_irq(&mdev->req_lock);
1278 _tl_restart(mdev, what); 1285 _tl_restart(mdev, what);
1279 _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL); 1286 nsm.i &= mdev->state.i;
1287 _drbd_set_state(mdev, nsm, CS_VERBOSE, NULL);
1280 spin_unlock_irq(&mdev->req_lock); 1288 spin_unlock_irq(&mdev->req_lock);
1281 } 1289 }
1282 1290
@@ -1298,7 +1306,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1298 if (get_ldev(mdev)) { 1306 if (get_ldev(mdev)) {
1299 if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && 1307 if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
1300 mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { 1308 mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
1301 if (mdev->state.susp) { 1309 if (is_susp(mdev->state)) {
1302 set_bit(NEW_CUR_UUID, &mdev->flags); 1310 set_bit(NEW_CUR_UUID, &mdev->flags);
1303 } else { 1311 } else {
1304 drbd_uuid_new_current(mdev); 1312 drbd_uuid_new_current(mdev);
@@ -1417,7 +1425,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
1417 resume_next_sg(mdev); 1425 resume_next_sg(mdev);
1418 1426
1419 /* free tl_hash if we Got thawed and are C_STANDALONE */ 1427 /* free tl_hash if we Got thawed and are C_STANDALONE */
1420 if (ns.conn == C_STANDALONE && ns.susp == 0 && mdev->tl_hash) 1428 if (ns.conn == C_STANDALONE && !is_susp(ns) && mdev->tl_hash)
1421 drbd_free_tl_hash(mdev); 1429 drbd_free_tl_hash(mdev);
1422 1430
1423 /* Upon network connection, we need to start the receiver */ 1431 /* Upon network connection, we need to start the receiver */
@@ -2732,7 +2740,9 @@ static void drbd_set_defaults(struct drbd_conf *mdev)
2732 .conn = C_STANDALONE, 2740 .conn = C_STANDALONE,
2733 .disk = D_DISKLESS, 2741 .disk = D_DISKLESS,
2734 .pdsk = D_UNKNOWN, 2742 .pdsk = D_UNKNOWN,
2735 .susp = 0 2743 .susp = 0,
2744 .susp_nod = 0,
2745 .susp_fen = 0
2736 } }; 2746 } };
2737} 2747}
2738 2748