aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_state.c')
-rw-r--r--drivers/block/drbd/drbd_state.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 1a84345a3868..a5d8aae00e04 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -54,8 +54,8 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os,
54static enum drbd_state_rv is_valid_state(struct drbd_device *, union drbd_state); 54static enum drbd_state_rv is_valid_state(struct drbd_device *, union drbd_state);
55static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state, struct drbd_connection *); 55static enum drbd_state_rv is_valid_soft_transition(union drbd_state, union drbd_state, struct drbd_connection *);
56static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns); 56static enum drbd_state_rv is_valid_transition(union drbd_state os, union drbd_state ns);
57static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state ns, 57static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state os,
58 enum sanitize_state_warnings *warn); 58 union drbd_state ns, enum sanitize_state_warnings *warn);
59 59
60static inline bool is_susp(union drbd_state s) 60static inline bool is_susp(union drbd_state s)
61{ 61{
@@ -287,7 +287,7 @@ _req_st_cond(struct drbd_device *device, union drbd_state mask,
287 287
288 spin_lock_irqsave(&device->resource->req_lock, flags); 288 spin_lock_irqsave(&device->resource->req_lock, flags);
289 os = drbd_read_state(device); 289 os = drbd_read_state(device);
290 ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); 290 ns = sanitize_state(device, os, apply_mask_val(os, mask, val), NULL);
291 rv = is_valid_transition(os, ns); 291 rv = is_valid_transition(os, ns);
292 if (rv >= SS_SUCCESS) 292 if (rv >= SS_SUCCESS)
293 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ 293 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
@@ -333,7 +333,7 @@ drbd_req_state(struct drbd_device *device, union drbd_state mask,
333 333
334 spin_lock_irqsave(&device->resource->req_lock, flags); 334 spin_lock_irqsave(&device->resource->req_lock, flags);
335 os = drbd_read_state(device); 335 os = drbd_read_state(device);
336 ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); 336 ns = sanitize_state(device, os, apply_mask_val(os, mask, val), NULL);
337 rv = is_valid_transition(os, ns); 337 rv = is_valid_transition(os, ns);
338 if (rv < SS_SUCCESS) { 338 if (rv < SS_SUCCESS) {
339 spin_unlock_irqrestore(&device->resource->req_lock, flags); 339 spin_unlock_irqrestore(&device->resource->req_lock, flags);
@@ -740,8 +740,8 @@ static void print_sanitize_warnings(struct drbd_device *device, enum sanitize_st
740 * When we loose connection, we have to set the state of the peers disk (pdsk) 740 * When we loose connection, we have to set the state of the peers disk (pdsk)
741 * to D_UNKNOWN. This rule and many more along those lines are in this function. 741 * to D_UNKNOWN. This rule and many more along those lines are in this function.
742 */ 742 */
743static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state ns, 743static union drbd_state sanitize_state(struct drbd_device *device, union drbd_state os,
744 enum sanitize_state_warnings *warn) 744 union drbd_state ns, enum sanitize_state_warnings *warn)
745{ 745{
746 enum drbd_fencing_p fp; 746 enum drbd_fencing_p fp;
747 enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max; 747 enum drbd_disk_state disk_min, disk_max, pdsk_min, pdsk_max;
@@ -882,11 +882,13 @@ static union drbd_state sanitize_state(struct drbd_device *device, union drbd_st
882 } 882 }
883 883
884 if (fp == FP_STONITH && 884 if (fp == FP_STONITH &&
885 (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED)) 885 (ns.role == R_PRIMARY && ns.conn < C_CONNECTED && ns.pdsk > D_OUTDATED) &&
886 !(os.role == R_PRIMARY && os.conn < C_CONNECTED && os.pdsk > D_OUTDATED))
886 ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */ 887 ns.susp_fen = 1; /* Suspend IO while fence-peer handler runs (peer lost) */
887 888
888 if (device->resource->res_opts.on_no_data == OND_SUSPEND_IO && 889 if (device->resource->res_opts.on_no_data == OND_SUSPEND_IO &&
889 (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE)) 890 (ns.role == R_PRIMARY && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) &&
891 !(os.role == R_PRIMARY && os.disk < D_UP_TO_DATE && os.pdsk < D_UP_TO_DATE))
890 ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */ 892 ns.susp_nod = 1; /* Suspend IO while no data available (no accessible data available) */
891 893
892 if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { 894 if (ns.aftr_isp || ns.peer_isp || ns.user_isp) {
@@ -958,7 +960,7 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
958 960
959 os = drbd_read_state(device); 961 os = drbd_read_state(device);
960 962
961 ns = sanitize_state(device, ns, &ssw); 963 ns = sanitize_state(device, os, ns, &ssw);
962 if (ns.i == os.i) 964 if (ns.i == os.i)
963 return SS_NOTHING_TO_DO; 965 return SS_NOTHING_TO_DO;
964 966
@@ -1656,7 +1658,7 @@ conn_is_valid_transition(struct drbd_connection *connection, union drbd_state ma
1656 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) { 1658 idr_for_each_entry(&connection->peer_devices, peer_device, vnr) {
1657 struct drbd_device *device = peer_device->device; 1659 struct drbd_device *device = peer_device->device;
1658 os = drbd_read_state(device); 1660 os = drbd_read_state(device);
1659 ns = sanitize_state(device, apply_mask_val(os, mask, val), NULL); 1661 ns = sanitize_state(device, os, apply_mask_val(os, mask, val), NULL);
1660 1662
1661 if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED) 1663 if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED)
1662 ns.disk = os.disk; 1664 ns.disk = os.disk;
@@ -1718,7 +1720,7 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union
1718 number_of_volumes++; 1720 number_of_volumes++;
1719 os = drbd_read_state(device); 1721 os = drbd_read_state(device);
1720 ns = apply_mask_val(os, mask, val); 1722 ns = apply_mask_val(os, mask, val);
1721 ns = sanitize_state(device, ns, NULL); 1723 ns = sanitize_state(device, os, ns, NULL);
1722 1724
1723 if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED) 1725 if (flags & CS_IGN_OUTD_FAIL && ns.disk == D_OUTDATED && os.disk < D_OUTDATED)
1724 ns.disk = os.disk; 1726 ns.disk = os.disk;
@@ -1763,19 +1765,19 @@ conn_set_state(struct drbd_connection *connection, union drbd_state mask, union
1763static enum drbd_state_rv 1765static enum drbd_state_rv
1764_conn_rq_cond(struct drbd_connection *connection, union drbd_state mask, union drbd_state val) 1766_conn_rq_cond(struct drbd_connection *connection, union drbd_state mask, union drbd_state val)
1765{ 1767{
1766 enum drbd_state_rv rv; 1768 enum drbd_state_rv err, rv = SS_UNKNOWN_ERROR; /* continue waiting */;
1767 1769
1768 if (test_and_clear_bit(CONN_WD_ST_CHG_OKAY, &connection->flags)) 1770 if (test_and_clear_bit(CONN_WD_ST_CHG_OKAY, &connection->flags))
1769 return SS_CW_SUCCESS; 1771 rv = SS_CW_SUCCESS;
1770 1772
1771 if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &connection->flags)) 1773 if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &connection->flags))
1772 return SS_CW_FAILED_BY_PEER; 1774 rv = SS_CW_FAILED_BY_PEER;
1773 1775
1774 rv = conn_is_valid_transition(connection, mask, val, 0); 1776 err = conn_is_valid_transition(connection, mask, val, 0);
1775 if (rv == SS_SUCCESS && connection->cstate == C_WF_REPORT_PARAMS) 1777 if (err == SS_SUCCESS && connection->cstate == C_WF_REPORT_PARAMS)
1776 rv = SS_UNKNOWN_ERROR; /* continue waiting */ 1778 return rv;
1777 1779
1778 return rv; 1780 return err;
1779} 1781}
1780 1782
1781enum drbd_state_rv 1783enum drbd_state_rv