diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-07-06 15:03:31 +0200 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-02-17 16:46:44 +0100 |
commit | b6f85ef9538b2111a8ba0bbfae9aaebabfc94961 (patch) | |
tree | ada222b0aff93fc6848d7365e92f933be9a29d84 /drivers/block/drbd/drbd_nl.c | |
parent | 270eb5c97258b9ae157d768fb19a42a685b41740 (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.c | 68 |
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; |