Loading drivers/block/drbd/drbd_state.c +75 −75 Original line number Diff line number Diff line Loading @@ -1378,9 +1378,6 @@ static void print_conn_state_change(struct drbd_tconn *tconn, enum drbd_conns oc } struct _is_valid_itr_params { enum chg_state_flags flags; union drbd_state mask, val; union drbd_state ms; /* maximal state, over all mdevs */ enum drbd_conns oc; enum { OC_UNINITIALIZED, Loading @@ -1389,26 +1386,19 @@ struct _is_valid_itr_params { } oc_state; }; static int _is_valid_itr_fn(int vnr, void *p, void *data) static enum drbd_state_rv conn_is_valid_transition(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val, enum chg_state_flags flags, struct _is_valid_itr_params *params) { struct drbd_conf *mdev = (struct drbd_conf *)p; struct _is_valid_itr_params *params = (struct _is_valid_itr_params *)data; enum chg_state_flags flags = params->flags; enum drbd_state_rv rv = SS_SUCCESS; union drbd_state ns, os; enum drbd_state_rv rv; struct drbd_conf *mdev; int vnr; params->oc_state = OC_UNINITIALIZED; idr_for_each_entry(&tconn->volumes, mdev, vnr) { os = mdev->state; ns = apply_mask_val(os, params->mask, params->val); ns = sanitize_state(mdev, ns, NULL); rv = is_valid_state(mdev, ns); if (rv < SS_SUCCESS) { /* If the old state was illegal as well, then let this happen...*/ if (is_valid_state(mdev, os) == rv) rv = is_valid_soft_transition(os, ns); } else rv = is_valid_soft_transition(os, ns); ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL); switch (params->oc_state) { case OC_UNINITIALIZED: Loading @@ -1423,35 +1413,59 @@ static int _is_valid_itr_fn(int vnr, void *p, void *data) break; } if (ns.i == os.i) continue; rv = is_valid_transition(os, ns); if (rv < SS_SUCCESS) break; if (!(flags & CS_HARD)) { rv = is_valid_state(mdev, ns); if (rv < SS_SUCCESS) { if (flags & CS_VERBOSE) if (is_valid_state(mdev, os) == rv) rv = is_valid_soft_transition(os, ns); } else rv = is_valid_soft_transition(os, ns); } if (rv < SS_SUCCESS) break; } if (rv < SS_SUCCESS && flags & CS_VERBOSE) print_st_err(mdev, os, ns, rv); return rv; } else return 0; } static int _set_state_itr_fn(int vnr, void *p, void *data) static union drbd_state conn_set_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val, enum chg_state_flags flags) { struct drbd_conf *mdev = (struct drbd_conf *)p; struct _is_valid_itr_params *params = (struct _is_valid_itr_params *)data; enum chg_state_flags flags = params->flags; union drbd_state os, ns, ms = params->ms; union drbd_state ns, os, ms = { }; struct drbd_conf *mdev; enum drbd_state_rv rv; int vnr; if (mask.conn == C_MASK) tconn->cstate = val.conn; idr_for_each_entry(&tconn->volumes, mdev, vnr) { os = mdev->state; ns = apply_mask_val(os, params->mask, params->val); ns = apply_mask_val(os, mask, val); ns = sanitize_state(mdev, ns, NULL); rv = __drbd_set_state(mdev, ns, flags, NULL); if (rv < SS_SUCCESS) BUG(); ms.role = max_role(ns.role, ms.role); ms.peer = max_role(ns.peer, ms.peer); ms.disk = max_t(enum drbd_role, mdev->state.disk, ms.disk); ms.pdsk = max_t(enum drbd_role, mdev->state.pdsk, ms.pdsk); params->ms = ms; ms.role = max_role(mdev->state.role, ms.role); ms.peer = max_role(mdev->state.peer, ms.peer); ms.disk = max_t(enum drbd_disk_state, mdev->state.disk, ms.disk); ms.pdsk = max_t(enum drbd_disk_state, mdev->state.pdsk, ms.pdsk); } return 0; return ms; } static enum drbd_state_rv Loading @@ -1466,17 +1480,13 @@ _conn_rq_cond(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags)) return SS_CW_FAILED_BY_PEER; params.flags = CS_NO_CSTATE_CHG; /* öö think */ params.mask = mask; params.val = val; spin_lock_irq(&tconn->req_lock); rv = tconn->cstate != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR; if (rv == SS_UNKNOWN_ERROR) rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, ¶ms); rv = conn_is_valid_transition(tconn, mask, val, CS_NO_CSTATE_CHG, ¶ms); if (rv == 0) /* idr_for_each semantics */ if (rv == SS_SUCCESS) rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ spin_unlock_irq(&tconn->req_lock); Loading Loading @@ -1517,22 +1527,13 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_ struct _is_valid_itr_params params; struct after_conn_state_chg_work *acscw; enum drbd_conns oc = tconn->cstate; union drbd_state ms; rv = is_valid_conn_transition(oc, val.conn); if (rv < SS_SUCCESS) goto abort; params.flags = flags; params.mask = mask; params.val = val; params.oc_state = OC_UNINITIALIZED; if (!(flags & CS_HARD)) rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, ¶ms); if (rv == 0) /* idr_for_each semantics */ rv = SS_SUCCESS; rv = conn_is_valid_transition(tconn, mask, val, flags, ¶ms); if (rv < SS_SUCCESS) goto abort; Loading @@ -1546,17 +1547,16 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_ if (params.oc_state == OC_CONSISTENT) { oc = params.oc; print_conn_state_change(tconn, oc, val.conn); params.flags |= CS_NO_CSTATE_CHG; flags |= CS_NO_CSTATE_CHG; } tconn->cstate = val.conn; params.ms.i = 0; params.ms.conn = val.conn; idr_for_each(&tconn->volumes, _set_state_itr_fn, ¶ms); ms = conn_set_state(tconn, mask, val, flags); ms.conn = val.conn; acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC); if (acscw) { acscw->oc = oc; acscw->nms = params.ms; acscw->nms = ms; acscw->flags = flags; acscw->w.cb = w_after_conn_state_ch; acscw->w.tconn = tconn; Loading Loading
drivers/block/drbd/drbd_state.c +75 −75 Original line number Diff line number Diff line Loading @@ -1378,9 +1378,6 @@ static void print_conn_state_change(struct drbd_tconn *tconn, enum drbd_conns oc } struct _is_valid_itr_params { enum chg_state_flags flags; union drbd_state mask, val; union drbd_state ms; /* maximal state, over all mdevs */ enum drbd_conns oc; enum { OC_UNINITIALIZED, Loading @@ -1389,26 +1386,19 @@ struct _is_valid_itr_params { } oc_state; }; static int _is_valid_itr_fn(int vnr, void *p, void *data) static enum drbd_state_rv conn_is_valid_transition(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val, enum chg_state_flags flags, struct _is_valid_itr_params *params) { struct drbd_conf *mdev = (struct drbd_conf *)p; struct _is_valid_itr_params *params = (struct _is_valid_itr_params *)data; enum chg_state_flags flags = params->flags; enum drbd_state_rv rv = SS_SUCCESS; union drbd_state ns, os; enum drbd_state_rv rv; struct drbd_conf *mdev; int vnr; params->oc_state = OC_UNINITIALIZED; idr_for_each_entry(&tconn->volumes, mdev, vnr) { os = mdev->state; ns = apply_mask_val(os, params->mask, params->val); ns = sanitize_state(mdev, ns, NULL); rv = is_valid_state(mdev, ns); if (rv < SS_SUCCESS) { /* If the old state was illegal as well, then let this happen...*/ if (is_valid_state(mdev, os) == rv) rv = is_valid_soft_transition(os, ns); } else rv = is_valid_soft_transition(os, ns); ns = sanitize_state(mdev, apply_mask_val(os, mask, val), NULL); switch (params->oc_state) { case OC_UNINITIALIZED: Loading @@ -1423,35 +1413,59 @@ static int _is_valid_itr_fn(int vnr, void *p, void *data) break; } if (ns.i == os.i) continue; rv = is_valid_transition(os, ns); if (rv < SS_SUCCESS) break; if (!(flags & CS_HARD)) { rv = is_valid_state(mdev, ns); if (rv < SS_SUCCESS) { if (flags & CS_VERBOSE) if (is_valid_state(mdev, os) == rv) rv = is_valid_soft_transition(os, ns); } else rv = is_valid_soft_transition(os, ns); } if (rv < SS_SUCCESS) break; } if (rv < SS_SUCCESS && flags & CS_VERBOSE) print_st_err(mdev, os, ns, rv); return rv; } else return 0; } static int _set_state_itr_fn(int vnr, void *p, void *data) static union drbd_state conn_set_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state val, enum chg_state_flags flags) { struct drbd_conf *mdev = (struct drbd_conf *)p; struct _is_valid_itr_params *params = (struct _is_valid_itr_params *)data; enum chg_state_flags flags = params->flags; union drbd_state os, ns, ms = params->ms; union drbd_state ns, os, ms = { }; struct drbd_conf *mdev; enum drbd_state_rv rv; int vnr; if (mask.conn == C_MASK) tconn->cstate = val.conn; idr_for_each_entry(&tconn->volumes, mdev, vnr) { os = mdev->state; ns = apply_mask_val(os, params->mask, params->val); ns = apply_mask_val(os, mask, val); ns = sanitize_state(mdev, ns, NULL); rv = __drbd_set_state(mdev, ns, flags, NULL); if (rv < SS_SUCCESS) BUG(); ms.role = max_role(ns.role, ms.role); ms.peer = max_role(ns.peer, ms.peer); ms.disk = max_t(enum drbd_role, mdev->state.disk, ms.disk); ms.pdsk = max_t(enum drbd_role, mdev->state.pdsk, ms.pdsk); params->ms = ms; ms.role = max_role(mdev->state.role, ms.role); ms.peer = max_role(mdev->state.peer, ms.peer); ms.disk = max_t(enum drbd_disk_state, mdev->state.disk, ms.disk); ms.pdsk = max_t(enum drbd_disk_state, mdev->state.pdsk, ms.pdsk); } return 0; return ms; } static enum drbd_state_rv Loading @@ -1466,17 +1480,13 @@ _conn_rq_cond(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state if (test_and_clear_bit(CONN_WD_ST_CHG_FAIL, &tconn->flags)) return SS_CW_FAILED_BY_PEER; params.flags = CS_NO_CSTATE_CHG; /* öö think */ params.mask = mask; params.val = val; spin_lock_irq(&tconn->req_lock); rv = tconn->cstate != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR; if (rv == SS_UNKNOWN_ERROR) rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, ¶ms); rv = conn_is_valid_transition(tconn, mask, val, CS_NO_CSTATE_CHG, ¶ms); if (rv == 0) /* idr_for_each semantics */ if (rv == SS_SUCCESS) rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ spin_unlock_irq(&tconn->req_lock); Loading Loading @@ -1517,22 +1527,13 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_ struct _is_valid_itr_params params; struct after_conn_state_chg_work *acscw; enum drbd_conns oc = tconn->cstate; union drbd_state ms; rv = is_valid_conn_transition(oc, val.conn); if (rv < SS_SUCCESS) goto abort; params.flags = flags; params.mask = mask; params.val = val; params.oc_state = OC_UNINITIALIZED; if (!(flags & CS_HARD)) rv = idr_for_each(&tconn->volumes, _is_valid_itr_fn, ¶ms); if (rv == 0) /* idr_for_each semantics */ rv = SS_SUCCESS; rv = conn_is_valid_transition(tconn, mask, val, flags, ¶ms); if (rv < SS_SUCCESS) goto abort; Loading @@ -1546,17 +1547,16 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_ if (params.oc_state == OC_CONSISTENT) { oc = params.oc; print_conn_state_change(tconn, oc, val.conn); params.flags |= CS_NO_CSTATE_CHG; flags |= CS_NO_CSTATE_CHG; } tconn->cstate = val.conn; params.ms.i = 0; params.ms.conn = val.conn; idr_for_each(&tconn->volumes, _set_state_itr_fn, ¶ms); ms = conn_set_state(tconn, mask, val, flags); ms.conn = val.conn; acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC); if (acscw) { acscw->oc = oc; acscw->nms = params.ms; acscw->nms = ms; acscw->flags = flags; acscw->w.cb = w_after_conn_state_ch; acscw->w.tconn = tconn; Loading