summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_state.c
diff options
context:
space:
mode:
authorPhilipp Reisner2011-03-24 11:03:07 +0100
committerPhilipp Reisner2012-11-08 16:44:53 +0100
commitcb703454a283d8dd5599e928eeea30367ca18874 (patch)
tree5e4c7553bc4dbbc3804c6ed6359a355a18b44159 /drivers/block/drbd/drbd_state.c
parentdrbd: Rename the DCBP_* functions to dcbp_* and move them to where they are used (diff)
downloadkernel-qcow2-linux-cb703454a283d8dd5599e928eeea30367ca18874.tar.gz
kernel-qcow2-linux-cb703454a283d8dd5599e928eeea30367ca18874.tar.xz
kernel-qcow2-linux-cb703454a283d8dd5599e928eeea30367ca18874.zip
drbd: Converted drbd_try_outdate_peer() from mdev to tconn
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_state.c')
-rw-r--r--drivers/block/drbd/drbd_state.c85
1 files changed, 70 insertions, 15 deletions
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 52ff1c7379e9..b4f668db3296 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -61,6 +61,73 @@ bool conn_all_vols_unconf(struct drbd_tconn *tconn)
return true;
}
+/* Unfortunately the states where not correctly ordered, when
+ they where defined. therefore can not use max_t() here. */
+static enum drbd_role max_role(enum drbd_role role1, enum drbd_role role2)
+{
+ if (role1 == R_PRIMARY || role2 == R_PRIMARY)
+ return R_PRIMARY;
+ if (role1 == R_SECONDARY || role2 == R_SECONDARY)
+ return R_SECONDARY;
+ return R_UNKNOWN;
+}
+static enum drbd_role min_role(enum drbd_role role1, enum drbd_role role2)
+{
+ if (role1 == R_UNKNOWN || role2 == R_UNKNOWN)
+ return R_UNKNOWN;
+ if (role1 == R_SECONDARY || role2 == R_SECONDARY)
+ return R_SECONDARY;
+ return R_PRIMARY;
+}
+
+enum drbd_role conn_highest_role(struct drbd_tconn *tconn)
+{
+ enum drbd_role role = R_UNKNOWN;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ role = max_role(role, mdev->state.role);
+
+ return role;
+}
+
+enum drbd_role conn_highest_peer(struct drbd_tconn *tconn)
+{
+ enum drbd_role peer = R_UNKNOWN;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ peer = max_role(peer, mdev->state.peer);
+
+ return peer;
+}
+
+enum drbd_disk_state conn_highest_disk(struct drbd_tconn *tconn)
+{
+ enum drbd_disk_state ds = D_DISKLESS;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ ds = max_t(enum drbd_disk_state, ds, mdev->state.disk);
+
+ return ds;
+}
+
+enum drbd_disk_state conn_highest_pdsk(struct drbd_tconn *tconn)
+{
+ enum drbd_disk_state ds = D_DISKLESS;
+ struct drbd_conf *mdev;
+ int vnr;
+
+ idr_for_each_entry(&tconn->volumes, mdev, vnr)
+ ds = max_t(enum drbd_disk_state, ds, mdev->state.pdsk);
+
+ return ds;
+}
+
/**
* cl_wide_st_chg() - true if the state change is a cluster wide one
* @mdev: DRBD device.
@@ -329,18 +396,6 @@ static void print_state_change(struct drbd_conf *mdev, union drbd_state os, unio
dev_info(DEV, "%s\n", pb);
}
-static bool vol_has_primary_peer(struct drbd_tconn *tconn)
-{
- struct drbd_conf *mdev;
- int vnr;
-
- idr_for_each_entry(&tconn->volumes, mdev, vnr) {
- if (mdev->state.peer == R_PRIMARY)
- return true;
- }
- return false;
-}
-
/**
* is_valid_state() - Returns an SS_ error code if ns is not valid
* @mdev: DRBD device.
@@ -364,7 +419,7 @@ is_valid_state(struct drbd_conf *mdev, union drbd_state ns)
if (!mdev->tconn->net_conf->two_primaries && ns.role == R_PRIMARY) {
if (ns.peer == R_PRIMARY)
rv = SS_TWO_PRIMARIES;
- else if (vol_has_primary_peer(mdev->tconn))
+ else if (conn_highest_peer(mdev->tconn) == R_PRIMARY)
rv = SS_O_VOL_PEER_PRI;
}
put_net_conf(mdev->tconn);
@@ -1390,8 +1445,8 @@ static int _set_state_itr_fn(int vnr, void *p, void *data)
rv = __drbd_set_state(mdev, ns, flags, NULL);
- ms.role = max_t(enum drbd_role, mdev->state.role, ms.role);
- ms.peer = max_t(enum drbd_role, mdev->state.peer, ms.peer);
+ 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;