diff options
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 36 |
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 | ||