summaryrefslogtreecommitdiff
path: root/drivers/block/drbd/drbd_nl.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-07-06 15:03:31 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2014-02-17 16:46:44 +0100
commitb6f85ef9538b2111a8ba0bbfae9aaebabfc94961 (patch)
treeada222b0aff93fc6848d7365e92f933be9a29d84 /drivers/block/drbd/drbd_nl.c
parent270eb5c97258b9ae157d768fb19a42a685b41740 (diff)
drbd: Iterate over all connections
in drbd_adm_down(), drbd_create_device() and drbd_set_role() Signed-off-by: Andreas Gruenbacher <agruen@linbit.com> Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_nl.c')
-rw-r--r--drivers/block/drbd/drbd_nl.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 33bc23fc55bb..8ebcf88b0c1b 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -560,8 +560,16 @@ drbd_set_role(struct drbd_device *device, enum drbd_role new_role, int force)
int forced = 0;
union drbd_state mask, val;
- if (new_role == R_PRIMARY)
- request_ping(first_peer_device(device)->connection); /* Detect a dead peer ASAP */
+ if (new_role == R_PRIMARY) {
+ struct drbd_connection *connection;
+
+ /* Detect dead peers as soon as possible. */
+
+ rcu_read_lock();
+ for_each_connection(connection, device->resource)
+ request_ping(connection);
+ rcu_read_unlock();
+ }
mutex_lock(device->state_mutex);
@@ -3387,8 +3395,10 @@ out:
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
{
+ struct drbd_resource *resource;
+ struct drbd_connection *connection;
+ struct drbd_device *device;
int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
- struct drbd_peer_device *peer_device;
unsigned i;
retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_RESOURCE);
@@ -3397,24 +3407,29 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
if (retcode != NO_ERROR)
goto out;
+ resource = adm_ctx.resource;
/* demote */
- idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
- retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0);
+ for_each_connection(connection, resource) {
+ struct drbd_peer_device *peer_device;
+
+ idr_for_each_entry(&connection->peer_devices, peer_device, i) {
+ retcode = drbd_set_role(peer_device->device, R_SECONDARY, 0);
+ if (retcode < SS_SUCCESS) {
+ drbd_msg_put_info("failed to demote");
+ goto out;
+ }
+ }
+
+ retcode = conn_try_disconnect(connection, 0);
if (retcode < SS_SUCCESS) {
- drbd_msg_put_info("failed to demote");
+ drbd_msg_put_info("failed to disconnect");
goto out;
}
}
- retcode = conn_try_disconnect(adm_ctx.connection, 0);
- if (retcode < SS_SUCCESS) {
- drbd_msg_put_info("failed to disconnect");
- goto out;
- }
-
/* detach */
- idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
- retcode = adm_detach(peer_device->device, 0);
+ idr_for_each_entry(&resource->devices, device, i) {
+ retcode = adm_detach(device, 0);
if (retcode < SS_SUCCESS || retcode > NO_ERROR) {
drbd_msg_put_info("failed to detach");
goto out;
@@ -3424,13 +3439,14 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
/* If we reach this, all volumes (of this connection) are Secondary,
* Disconnected, Diskless, aka Unconfigured. Make sure all threads have
* actually stopped, state handling only does drbd_thread_stop_nowait(). */
- drbd_thread_stop(&adm_ctx.connection->worker);
+ for_each_connection(connection, resource)
+ drbd_thread_stop(&connection->worker);
/* Now, nothing can fail anymore */
/* delete volumes */
- idr_for_each_entry(&adm_ctx.connection->peer_devices, peer_device, i) {
- retcode = adm_del_minor(peer_device->device);
+ idr_for_each_entry(&resource->devices, device, i) {
+ retcode = adm_del_minor(device);
if (retcode != NO_ERROR) {
/* "can not happen" */
drbd_msg_put_info("failed to delete volume");
@@ -3438,21 +3454,11 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
}
}
- /* delete connection */
- if (conn_lowest_minor(adm_ctx.connection) < 0) {
- struct drbd_resource *resource = adm_ctx.connection->resource;
-
- list_del_rcu(&resource->resources);
- synchronize_rcu();
- drbd_free_resource(resource);
+ list_del_rcu(&resource->resources);
+ synchronize_rcu();
+ drbd_free_resource(resource);
+ retcode = NO_ERROR;
- retcode = NO_ERROR;
- } else {
- /* "can not happen" */
- retcode = ERR_RES_IN_USE;
- drbd_msg_put_info("failed to delete connection");
- }
- goto out;
out:
drbd_adm_finish(info, retcode);
return 0;