Commit bd0c824a authored by Philipp Reisner's avatar Philipp Reisner
Browse files

drbd: Use the idr_for_each_entry() iterator instead of idr_for_each()

parent 4a76b161
Loading
Loading
Loading
Loading
+75 −75
Original line number Diff line number Diff line
@@ -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,
@@ -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:
@@ -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
@@ -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, &params);
		rv = conn_is_valid_transition(tconn, mask, val, CS_NO_CSTATE_CHG, &params);

	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);
@@ -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, &params);

	if (rv == 0)  /* idr_for_each semantics */
		rv = SS_SUCCESS;

	rv = conn_is_valid_transition(tconn, mask, val, flags, &params);
	if (rv < SS_SUCCESS)
		goto abort;

@@ -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, &params);

	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;