diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-07-05 12:23:07 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2014-02-17 10:46:38 -0500 |
commit | 251b8f8eafcb8f3d6c11b061d23eddf7c0723da7 (patch) | |
tree | 85e0d9e9efdac67bd3a6c051203720bbcfc3a823 /drivers | |
parent | f82795d683333a4701ab48b0d422ebbc437f25a5 (diff) |
drbd: get_one_status(): Iterate over resource->devices instead of connection->peer_devices
Signed-off-by: Andreas Gruenbacher <agruen@linbit.com>
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 81e07e2664b3..6f11d8579263 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -2752,23 +2752,28 @@ int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info) | |||
2752 | return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED)); | 2752 | return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED)); |
2753 | } | 2753 | } |
2754 | 2754 | ||
2755 | static int nla_put_drbd_cfg_context(struct sk_buff *skb, struct drbd_connection *connection, unsigned vnr) | 2755 | static int nla_put_drbd_cfg_context(struct sk_buff *skb, |
2756 | struct drbd_resource *resource, | ||
2757 | struct drbd_connection *connection, | ||
2758 | struct drbd_device *device) | ||
2756 | { | 2759 | { |
2757 | struct nlattr *nla; | 2760 | struct nlattr *nla; |
2758 | nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT); | 2761 | nla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT); |
2759 | if (!nla) | 2762 | if (!nla) |
2760 | goto nla_put_failure; | 2763 | goto nla_put_failure; |
2761 | if (vnr != VOLUME_UNSPECIFIED && | 2764 | if (device && |
2762 | nla_put_u32(skb, T_ctx_volume, vnr)) | 2765 | nla_put_u32(skb, T_ctx_volume, device->vnr)) |
2763 | goto nla_put_failure; | 2766 | goto nla_put_failure; |
2764 | if (nla_put_string(skb, T_ctx_resource_name, connection->resource->name)) | 2767 | if (nla_put_string(skb, T_ctx_resource_name, connection->resource->name)) |
2765 | goto nla_put_failure; | 2768 | goto nla_put_failure; |
2766 | if (connection->my_addr_len && | 2769 | if (connection) { |
2767 | nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr)) | 2770 | if (connection->my_addr_len && |
2768 | goto nla_put_failure; | 2771 | nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr)) |
2769 | if (connection->peer_addr_len && | 2772 | goto nla_put_failure; |
2770 | nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr)) | 2773 | if (connection->peer_addr_len && |
2771 | goto nla_put_failure; | 2774 | nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr)) |
2775 | goto nla_put_failure; | ||
2776 | } | ||
2772 | nla_nest_end(skb, nla); | 2777 | nla_nest_end(skb, nla); |
2773 | return 0; | 2778 | return 0; |
2774 | 2779 | ||
@@ -2778,9 +2783,22 @@ nla_put_failure: | |||
2778 | return -EMSGSIZE; | 2783 | return -EMSGSIZE; |
2779 | } | 2784 | } |
2780 | 2785 | ||
2781 | static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, | 2786 | /* |
2787 | * Return the connection of @resource if @resource has exactly one connection. | ||
2788 | */ | ||
2789 | static struct drbd_connection *the_only_connection(struct drbd_resource *resource) | ||
2790 | { | ||
2791 | struct list_head *connections = &resource->connections; | ||
2792 | |||
2793 | if (list_empty(connections) || connections->next->next != connections) | ||
2794 | return NULL; | ||
2795 | return list_first_entry(&resource->connections, struct drbd_connection, connections); | ||
2796 | } | ||
2797 | |||
2798 | int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, | ||
2782 | const struct sib_info *sib) | 2799 | const struct sib_info *sib) |
2783 | { | 2800 | { |
2801 | struct drbd_resource *resource = device->resource; | ||
2784 | struct state_info *si = NULL; /* for sizeof(si->member); */ | 2802 | struct state_info *si = NULL; /* for sizeof(si->member); */ |
2785 | struct nlattr *nla; | 2803 | struct nlattr *nla; |
2786 | int got_ldev; | 2804 | int got_ldev; |
@@ -2804,7 +2822,7 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, | |||
2804 | 2822 | ||
2805 | /* We need to add connection name and volume number information still. | 2823 | /* We need to add connection name and volume number information still. |
2806 | * Minor number is in drbd_genlmsghdr. */ | 2824 | * Minor number is in drbd_genlmsghdr. */ |
2807 | if (nla_put_drbd_cfg_context(skb, first_peer_device(device)->connection, device->vnr)) | 2825 | if (nla_put_drbd_cfg_context(skb, resource, the_only_connection(resource), device)) |
2808 | goto nla_put_failure; | 2826 | goto nla_put_failure; |
2809 | 2827 | ||
2810 | if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive)) | 2828 | if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive)) |
@@ -2922,19 +2940,17 @@ out: | |||
2922 | 2940 | ||
2923 | static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) | 2941 | static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) |
2924 | { | 2942 | { |
2925 | struct drbd_peer_device *peer_device; | ||
2926 | struct drbd_device *device; | 2943 | struct drbd_device *device; |
2927 | struct drbd_genlmsghdr *dh; | 2944 | struct drbd_genlmsghdr *dh; |
2928 | struct drbd_resource *pos = (struct drbd_resource *)cb->args[0]; | 2945 | struct drbd_resource *pos = (struct drbd_resource *)cb->args[0]; |
2929 | struct drbd_resource *resource = NULL; | 2946 | struct drbd_resource *resource = NULL; |
2930 | struct drbd_connection *connection; | ||
2931 | struct drbd_resource *tmp; | 2947 | struct drbd_resource *tmp; |
2932 | unsigned volume = cb->args[1]; | 2948 | unsigned volume = cb->args[1]; |
2933 | 2949 | ||
2934 | /* Open coded, deferred, iteration: | 2950 | /* Open coded, deferred, iteration: |
2935 | * for_each_resource_safe(resource, tmp, &drbd_resources) { | 2951 | * for_each_resource_safe(resource, tmp, &drbd_resources) { |
2936 | * connection = "first connection of resource"; | 2952 | * connection = "first connection of resource or undefined"; |
2937 | * idr_for_each_entry(&connection->peer_devices, peer_device, i) { | 2953 | * idr_for_each_entry(&resource->devices, device, i) { |
2938 | * ... | 2954 | * ... |
2939 | * } | 2955 | * } |
2940 | * } | 2956 | * } |
@@ -2969,9 +2985,8 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb) | |||
2969 | } | 2985 | } |
2970 | if (resource) { | 2986 | if (resource) { |
2971 | next_resource: | 2987 | next_resource: |
2972 | connection = first_connection(resource); | 2988 | device = idr_get_next(&resource->devices, &volume); |
2973 | peer_device = idr_get_next(&connection->peer_devices, &volume); | 2989 | if (!device) { |
2974 | if (!peer_device) { | ||
2975 | /* No more volumes to dump on this resource. | 2990 | /* No more volumes to dump on this resource. |
2976 | * Advance resource iterator. */ | 2991 | * Advance resource iterator. */ |
2977 | pos = list_entry_rcu(resource->resources.next, | 2992 | pos = list_entry_rcu(resource->resources.next, |
@@ -2995,24 +3010,29 @@ next_resource: | |||
2995 | if (!dh) | 3010 | if (!dh) |
2996 | goto out; | 3011 | goto out; |
2997 | 3012 | ||
2998 | if (!peer_device) { | 3013 | if (!device) { |
2999 | /* This is a connection without a single volume. | 3014 | /* This is a connection without a single volume. |
3000 | * Suprisingly enough, it may have a network | 3015 | * Suprisingly enough, it may have a network |
3001 | * configuration. */ | 3016 | * configuration. */ |
3002 | struct net_conf *nc; | 3017 | struct drbd_connection *connection; |
3018 | |||
3003 | dh->minor = -1U; | 3019 | dh->minor = -1U; |
3004 | dh->ret_code = NO_ERROR; | 3020 | dh->ret_code = NO_ERROR; |
3005 | if (nla_put_drbd_cfg_context(skb, connection, VOLUME_UNSPECIFIED)) | 3021 | connection = the_only_connection(resource); |
3006 | goto cancel; | 3022 | if (nla_put_drbd_cfg_context(skb, resource, connection, NULL)) |
3007 | nc = rcu_dereference(connection->net_conf); | ||
3008 | if (nc && net_conf_to_skb(skb, nc, 1) != 0) | ||
3009 | goto cancel; | 3023 | goto cancel; |
3024 | if (connection) { | ||
3025 | struct net_conf *nc; | ||
3026 | |||
3027 | nc = rcu_dereference(connection->net_conf); | ||
3028 | if (nc && net_conf_to_skb(skb, nc, 1) != 0) | ||
3029 | goto cancel; | ||
3030 | } | ||
3010 | goto done; | 3031 | goto done; |
3011 | } | 3032 | } |
3012 | 3033 | ||
3013 | device = peer_device->device; | ||
3014 | D_ASSERT(device, device->vnr == volume); | 3034 | D_ASSERT(device, device->vnr == volume); |
3015 | D_ASSERT(device, first_peer_device(device)->connection == connection); | 3035 | D_ASSERT(device, device->resource == resource); |
3016 | 3036 | ||
3017 | dh->minor = device_to_minor(device); | 3037 | dh->minor = device_to_minor(device); |
3018 | dh->ret_code = NO_ERROR; | 3038 | dh->ret_code = NO_ERROR; |