Commit 251b8f8e authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner

drbd: get_one_status(): Iterate over resource->devices instead of connection->peer_devices

Signed-off-by: default avatarAndreas Gruenbacher <agruen@linbit.com>
Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
parent f82795d6
...@@ -2752,23 +2752,28 @@ int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info) ...@@ -2752,23 +2752,28 @@ int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info)
return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED)); return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED));
} }
static int nla_put_drbd_cfg_context(struct sk_buff *skb, struct drbd_connection *connection, unsigned vnr) static int nla_put_drbd_cfg_context(struct sk_buff *skb,
struct drbd_resource *resource,
struct drbd_connection *connection,
struct drbd_device *device)
{ {
struct nlattr *nla; struct nlattr *nla;
nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT); nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT);
if (!nla) if (!nla)
goto nla_put_failure; goto nla_put_failure;
if (vnr != VOLUME_UNSPECIFIED && if (device &&
nla_put_u32(skb, T_ctx_volume, vnr)) nla_put_u32(skb, T_ctx_volume, device->vnr))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_string(skb, T_ctx_resource_name, connection->resource->name)) if (nla_put_string(skb, T_ctx_resource_name, connection->resource->name))
goto nla_put_failure; goto nla_put_failure;
if (connection) {
if (connection->my_addr_len && if (connection->my_addr_len &&
nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr)) nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr))
goto nla_put_failure; goto nla_put_failure;
if (connection->peer_addr_len && if (connection->peer_addr_len &&
nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr)) nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr))
goto nla_put_failure; goto nla_put_failure;
}
nla_nest_end(skb, nla); nla_nest_end(skb, nla);
return 0; return 0;
...@@ -2778,9 +2783,22 @@ static int nla_put_drbd_cfg_context(struct sk_buff *skb, struct drbd_connection ...@@ -2778,9 +2783,22 @@ static int nla_put_drbd_cfg_context(struct sk_buff *skb, struct drbd_connection
return -EMSGSIZE; return -EMSGSIZE;
} }
static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, /*
* Return the connection of @resource if @resource has exactly one connection.
*/
static struct drbd_connection *the_only_connection(struct drbd_resource *resource)
{
struct list_head *connections = &resource->connections;
if (list_empty(connections) || connections->next->next != connections)
return NULL;
return list_first_entry(&resource->connections, struct drbd_connection, connections);
}
int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
const struct sib_info *sib) const struct sib_info *sib)
{ {
struct drbd_resource *resource = device->resource;
struct state_info *si = NULL; /* for sizeof(si->member); */ struct state_info *si = NULL; /* for sizeof(si->member); */
struct nlattr *nla; struct nlattr *nla;
int got_ldev; int got_ldev;
...@@ -2804,7 +2822,7 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, ...@@ -2804,7 +2822,7 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
/* We need to add connection name and volume number information still. /* We need to add connection name and volume number information still.
* Minor number is in drbd_genlmsghdr. */ * Minor number is in drbd_genlmsghdr. */
if (nla_put_drbd_cfg_context(skb, first_peer_device(device)->connection, device->vnr)) if (nla_put_drbd_cfg_context(skb, resource, the_only_connection(resource), device))
goto nla_put_failure; goto nla_put_failure;
if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive)) if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive))
...@@ -2922,19 +2940,17 @@ int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info) ...@@ -2922,19 +2940,17 @@ int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info)
static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct drbd_peer_device *peer_device;
struct drbd_device *device; struct drbd_device *device;
struct drbd_genlmsghdr *dh; struct drbd_genlmsghdr *dh;
struct drbd_resource *pos = (struct drbd_resource *)cb->args[0]; struct drbd_resource *pos = (struct drbd_resource *)cb->args[0];
struct drbd_resource *resource = NULL; struct drbd_resource *resource = NULL;
struct drbd_connection *connection;
struct drbd_resource *tmp; struct drbd_resource *tmp;
unsigned volume = cb->args[1]; unsigned volume = cb->args[1];
/* Open coded, deferred, iteration: /* Open coded, deferred, iteration:
* for_each_resource_safe(resource, tmp, &drbd_resources) { * for_each_resource_safe(resource, tmp, &drbd_resources) {
* connection = "first connection of resource"; * connection = "first connection of resource or undefined";
* idr_for_each_entry(&connection->peer_devices, peer_device, i) { * idr_for_each_entry(&resource->devices, device, i) {
* ... * ...
* } * }
* } * }
...@@ -2969,9 +2985,8 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2969,9 +2985,8 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
} }
if (resource) { if (resource) {
next_resource: next_resource:
connection = first_connection(resource); device = idr_get_next(&resource->devices, &volume);
peer_device = idr_get_next(&connection->peer_devices, &volume); if (!device) {
if (!peer_device) {
/* No more volumes to dump on this resource. /* No more volumes to dump on this resource.
* Advance resource iterator. */ * Advance resource iterator. */
pos = list_entry_rcu(resource->resources.next, pos = list_entry_rcu(resource->resources.next,
...@@ -2995,24 +3010,29 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2995,24 +3010,29 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
if (!dh) if (!dh)
goto out; goto out;
if (!peer_device) { if (!device) {
/* This is a connection without a single volume. /* This is a connection without a single volume.
* Suprisingly enough, it may have a network * Suprisingly enough, it may have a network
* configuration. */ * configuration. */
struct net_conf *nc; struct drbd_connection *connection;
dh->minor = -1U; dh->minor = -1U;
dh->ret_code = NO_ERROR; dh->ret_code = NO_ERROR;
if (nla_put_drbd_cfg_context(skb, connection, VOLUME_UNSPECIFIED)) connection = the_only_connection(resource);
if (nla_put_drbd_cfg_context(skb, resource, connection, NULL))
goto cancel; goto cancel;
if (connection) {
struct net_conf *nc;
nc = rcu_dereference(connection->net_conf); nc = rcu_dereference(connection->net_conf);
if (nc && net_conf_to_skb(skb, nc, 1) != 0) if (nc && net_conf_to_skb(skb, nc, 1) != 0)
goto cancel; goto cancel;
}
goto done; goto done;
} }
device = peer_device->device;
D_ASSERT(device, device->vnr == volume); D_ASSERT(device, device->vnr == volume);
D_ASSERT(device, first_peer_device(device)->connection == connection); D_ASSERT(device, device->resource == resource);
dh->minor = device_to_minor(device); dh->minor = device_to_minor(device);
dh->ret_code = NO_ERROR; dh->ret_code = NO_ERROR;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment