History

drbd: replace genl_magic with explicit netlink serialization

Replace the genl_magic multi-include macro system with explicit serialization and parsing. The *_gen files were initially produced from a YNL spec via a customized ynl-gen-c, but the DRBD netlink family is effectively frozen, so the generator is kept unmodified. All new functionality will land in a separate, properly-designed family. Carry the resulting code as ordinary in-tree source rather than landing the spec and generator changes that produced it. The bulk of the changes are mechanical renames to fit the YNL naming conventions: - Handler functions: drbd_adm_* -> drbd_nl_*_doit/dumpit - GENL_MAGIC_VERSION -> DRBD_FAMILY_VERSION - GENL_MAGIC_FAMILY_HDRSZ -> sizeof(struct drbd_genlmsghdr) - drbd_genl_family -> drbd_nl_family - Attribute IDs: T_* -> DRBD_A_* Remove the nested_attr_tb static global buffer and move to a per-call allocation approach: each deserialization manages its own nested attribute table. This will be needed anyway when we eventually move to parallel_ops, and it's actually simpler this way, so make the move now. Replace the functionality of the "sensitive" flag: this was only used by a single field (shared_secret); open-code redaction logic for that locally. Also replace the "invariant" flag: this only had a couple of users, and those basically never change. Hard code the check directly inline. The genl_family struct itself is defined manually in drbd_nl.c. Also replace a couple of drbd-specific wrappers (nla_put_u64_0pad, drbd_nla_find_nested) with standard kernel functions while we're at it. Finally, completely remove the genl_magic system; DRBD was its only user.

Christoph Böhmwalder committed 6 months ago

Commit 8098eeb1 parent a54f49914 files · +3609 −1422Browse files

Unified · Split

14 files
  1. drivers/block/drbd/Makefile +1 −0
  2. drivers/block/drbd/drbd_debugfs.c +1 −1
  3. drivers/block/drbd/drbd_int.h +3 −1
  4. drivers/block/drbd/drbd_main.c +3 −3
  5. drivers/block/drbd/drbd_nl.c +237 −179
  6. drivers/block/drbd/drbd_nl_gen.c +2606 −0
  7. drivers/block/drbd/drbd_nl_gen.h +395 −0
  8. drivers/block/drbd/drbd_proc.c +1 −1
  9. include/linux/drbd_genl.h +0 −536
  10. include/linux/drbd_genl_api.h +0 −16
  11. include/linux/genl_magic_func.h +0 −413
  12. include/linux/genl_magic_struct.h +0 −272
  13. include/uapi/linux/drbd.h +3 −0
  14. include/uapi/linux/drbd_genl.h +359 −0
drivers/block/drbd/Makefile+1−0
@@ -3,6 +3,7 @@ drbd-y := drbd_buildtag.o drbd_bitmap.o drbd_proc.o · 2 unmodified lines
33 drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
44 drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
55 drbd-y += drbd_interval.o drbd_state.o
6+drbd-y += drbd_nl_gen.o
67 drbd-$(CONFIG_DEBUG_FS) += drbd_debugfs.o
78
89 obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o
drivers/block/drbd/drbd_debugfs.c+1−1
@@ -844,7 +844,7 @@ static int drbd_version_show(struct seq_file *m, void *ignored) · 843 unmodified lines
844844 {
845845 seq_printf(m, "# %s\n", drbd_buildtag());
846846 seq_printf(m, "VERSION=%s\n", REL_VERSION);
847− seq_printf(m, "API_VERSION=%u\n", GENL_MAGIC_VERSION);
847+ seq_printf(m, "API_VERSION=%u\n", DRBD_FAMILY_VERSION);
848848 seq_printf(m, "PRO_VERSION_MIN=%u\n", PRO_VERSION_MIN);
849849 seq_printf(m, "PRO_VERSION_MAX=%u\n", PRO_VERSION_MAX);
850850 return 0;
drivers/block/drbd/drbd_int.h+3−1
@@ -32,14 +32,16 @@ · 31 unmodified lines
3232 #include <net/tcp.h>
3333 #include <linux/lru_cache.h>
3434 #include <linux/prefetch.h>
35−#include <linux/drbd_genl_api.h>
3635 #include <linux/drbd.h>
3736 #include "drbd_config.h"
37+#include "drbd_nl_gen.h"
3838 #include "drbd_strings.h"
3939 #include "drbd_state.h"
4040 #include "drbd_protocol.h"
4141 #include "drbd_polymorph_printk.h"
4242
43+extern struct genl_family drbd_nl_family;
44+
4345 /* shared module parameters, defined in drbd_main.c */
4446 #ifdef CONFIG_DRBD_FAULT_INJECTION
4547 extern int drbd_enable_faults;
drivers/block/drbd/drbd_main.c+3−3
@@ -2324,7 +2324,7 @@ static void drbd_cleanup(void) · 2323 unmodified lines
23242324 if (retry.wq)
23252325 destroy_workqueue(retry.wq);
23262326
2327− drbd_genl_unregister();
2327+ genl_unregister_family(&drbd_nl_family);
23282328
23292329 idr_for_each_entry(&drbd_devices, device, i)
23302330 drbd_delete_device(device);
@@ -2846,7 +2846,7 @@ static int __init drbd_init(void) · 515 unmodified lines
28462846 mutex_init(&resources_mutex);
28472847 INIT_LIST_HEAD(&drbd_resources);
28482848
2849− err = drbd_genl_register();
2849+ err = genl_register_family(&drbd_nl_family);
28502850 if (err) {
28512851 pr_err("unable to register generic netlink family\n");
28522852 goto fail;
@@ -2876,7 +2876,7 @@ static int __init drbd_init(void) · 23 unmodified lines
28762876
28772877 pr_info("initialized. "
28782878 "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n",
2879− GENL_MAGIC_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
2879+ DRBD_FAMILY_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
28802880 pr_info("%s\n", drbd_buildtag());
28812881 pr_info("registered as block device major %d\n", DRBD_MAJOR);
28822882 return 0; /* Success! */
drivers/block/drbd/drbd_nl.c+237−179
@@ -31,59 +31,13 @@ · 30 unmodified lines
3131
3232 #include <net/genetlink.h>
3333
34−/* .doit */
35−// int drbd_adm_create_resource(struct sk_buff *skb, struct genl_info *info);
36−// int drbd_adm_delete_resource(struct sk_buff *skb, struct genl_info *info);
37−
38−int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info);
39−int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info);
40−
41−int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info);
42−int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info);
43−int drbd_adm_down(struct sk_buff *skb, struct genl_info *info);
44−
45−int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info);
46−int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info);
47−int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info);
48−int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info);
49−int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info);
50−int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info);
51−int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info);
52−int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info);
53−int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info);
54−int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info);
55−int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info);
56−int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info);
57−int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info);
58−int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info);
59−int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info);
60−int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info);
61−int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info);
62−int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info);
63−int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info);
64−int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info);
65−/* .dumpit */
66−int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb);
67−int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb);
68−int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb);
69−int drbd_adm_dump_devices_done(struct netlink_callback *cb);
70−int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb);
71−int drbd_adm_dump_connections_done(struct netlink_callback *cb);
72−int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb);
73−int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb);
74−int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb);
75−
76−#include <linux/drbd_genl_api.h>
77−
78−static int drbd_pre_doit(const struct genl_split_ops *ops,
79− struct sk_buff *skb, struct genl_info *info);
80−static void drbd_post_doit(const struct genl_split_ops *ops,
81− struct sk_buff *skb, struct genl_info *info);
82−
83−#define GENL_MAGIC_FAMILY_PRE_DOIT drbd_pre_doit
84−#define GENL_MAGIC_FAMILY_POST_DOIT drbd_post_doit
85−
86−#include <linux/genl_magic_func.h>
34+#include "drbd_nl_gen.h"
35+
36+static int drbd_genl_multicast_events(struct sk_buff *skb, gfp_t flags)
37+{
38+ return genlmsg_multicast(&drbd_nl_family, skb, 0,
39+ DRBD_NLGRP_EVENTS, flags);
40+}
8741
8842 static atomic_t drbd_genl_seq = ATOMIC_INIT(2); /* two. */
8943 static atomic_t notify_genl_seq = ATOMIC_INIT(2); /* two. */
@@ -114,7 +68,7 @@ static int drbd_msg_put_info(struct sk_buff *skb, const char *info) · 24 unmodified lines
11468 if (!nla)
11569 return err;
11670
117− err = nla_put_string(skb, T_info_text, info);
71+ err = nla_put_string(skb, DRBD_A_DRBD_CFG_REPLY_INFO_TEXT, info);
11872 if (err) {
11973 nla_nest_cancel(skb, nla);
12074 return err;
@@ -135,7 +89,7 @@ static int drbd_msg_sprintf_info(struct sk_buff *skb, const char *fmt, ...) · 14 unmodified lines
13589 if (!nla)
13690 return err;
13791
138− txt = nla_reserve(skb, T_info_text, 256);
92+ txt = nla_reserve(skb, DRBD_A_DRBD_CFG_REPLY_INFO_TEXT, 256);
13993 if (!txt) {
14094 nla_nest_cancel(skb, nla);
14195 return err;
@@ -187,6 +141,15 @@ static const unsigned int drbd_genl_cmd_flags[] = { · 45 unmodified lines
187141 [DRBD_ADM_DOWN] = DRBD_ADM_NEED_RESOURCE,
188142 };
189143
144+/* Detect attempts to change invariant attributes in a _change_ handler. */
145+#define has_invariant(ntb, attr) \
146+({ \
147+ bool __found = !!(ntb)[attr]; \
148+ if (__found) \
149+ pr_info("must not change invariant attr: %s\n", #attr); \
150+ __found; \
151+})
152+
190153 /*
191154 * At this point, we still rely on the global genl_lock().
192155 * If we want to avoid that, and allow "genl_family.parallel_ops", we may need
@@ -210,7 +173,7 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx, · 17 unmodified lines
210173 }
211174
212175 adm_ctx->reply_dh = genlmsg_put_reply(adm_ctx->reply_skb,
213− info, &drbd_genl_family, 0, cmd);
176+ info, &drbd_nl_family, 0, cmd);
214177 /* put of a few bytes into a fresh skb of >= 4k will always succeed.
215178 * but anyways */
216179 if (!adm_ctx->reply_dh) {
@@ -223,9 +186,11 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx, · 6 unmodified lines
223186
224187 adm_ctx->volume = VOLUME_UNSPECIFIED;
225188 if (info->attrs[DRBD_NLA_CFG_CONTEXT]) {
189+ struct nlattr **ntb;
226190 struct nlattr *nla;
227− /* parse and validate only */
228− err = drbd_cfg_context_from_attrs(NULL, info);
191+
192+ /* parse and validate, get nested attribute table */
193+ err = drbd_cfg_context_ntb_from_attrs(&ntb, info);
229194 if (err)
230195 goto fail;
231196
@@ -234,18 +199,21 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx, · 2 unmodified lines
234199 err = nla_put_nohdr(adm_ctx->reply_skb,
235200 info->attrs[DRBD_NLA_CFG_CONTEXT]->nla_len,
236201 info->attrs[DRBD_NLA_CFG_CONTEXT]);
237− if (err)
202+ if (err) {
203+ kfree(ntb);
238204 goto fail;
205+ }
239206
240207 /* and assign stuff to the adm_ctx */
241− nla = nested_attr_tb[T_ctx_volume];
208+ nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME];
242209 if (nla)
243210 adm_ctx->volume = nla_get_u32(nla);
244− nla = nested_attr_tb[T_ctx_resource_name];
211+ nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME];
245212 if (nla)
246213 adm_ctx->resource_name = nla_data(nla);
247− adm_ctx->my_addr = nested_attr_tb[T_ctx_my_addr];
248− adm_ctx->peer_addr = nested_attr_tb[T_ctx_peer_addr];
214+ adm_ctx->my_addr = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR];
215+ adm_ctx->peer_addr = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR];
216+ kfree(ntb);
249217 if ((adm_ctx->my_addr &&
250218 nla_len(adm_ctx->my_addr) > sizeof(adm_ctx->connection->my_addr)) ||
251219 (adm_ctx->peer_addr &&
@@ -259,7 +227,7 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx, · 7 unmodified lines
259227 adm_ctx->device = minor_to_device(d_in->minor);
260228
261229 /* We are protected by the global genl_lock().
262− * But we may explicitly drop it/retake it in drbd_adm_set_role(),
230+ * But we may explicitly drop it/retake it in drbd_nl_set_role(),
263231 * so make sure this object stays around. */
264232 if (adm_ctx->device)
265233 kref_get(&adm_ctx->device->kref);
@@ -334,8 +302,8 @@ fail: · 68 unmodified lines
334302 return err;
335303 }
336304
337−static int drbd_pre_doit(const struct genl_split_ops *ops,
338− struct sk_buff *skb, struct genl_info *info)
305+int drbd_pre_doit(const struct genl_split_ops *ops,
306+ struct sk_buff *skb, struct genl_info *info)
339307 {
340308 struct drbd_config_context *adm_ctx;
341309 u8 cmd = info->genlhdr->cmd;
@@ -362,8 +330,8 @@ static int drbd_pre_doit(const struct genl_split_ops *ops, · 20 unmodified lines
362330 return 0;
363331 }
364332
365−static void drbd_post_doit(const struct genl_split_ops *ops,
366− struct sk_buff *skb, struct genl_info *info)
333+void drbd_post_doit(const struct genl_split_ops *ops,
334+ struct sk_buff *skb, struct genl_info *info)
367335 {
368336 struct drbd_config_context *adm_ctx = info->user_ptr[0];
369337
@@ -828,7 +796,7 @@ static const char *from_attrs_err_to_txt(int err) · 458 unmodified lines
828796 "invalid attribute value";
829797 }
830798
831−int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info)
799+static int drbd_nl_set_role(struct sk_buff *skb, struct genl_info *info)
832800 {
833801 struct drbd_config_context *adm_ctx = info->user_ptr[0];
834802 struct set_role_parms parms;
@@ -868,6 +836,16 @@ out: · 33 unmodified lines
868836 return 0;
869837 }
870838
839+int drbd_nl_primary_doit(struct sk_buff *skb, struct genl_info *info)
840+{
841+ return drbd_nl_set_role(skb, info);
842+}
843+
844+int drbd_nl_secondary_doit(struct sk_buff *skb, struct genl_info *info)
845+{
846+ return drbd_nl_set_role(skb, info);
847+}
848+
871849 /* Initializes the md.*_offset members, so we are able to find
872850 * the on disk meta data.
873851 *
@@ -962,7 +940,7 @@ char *ppsize(char *buf, unsigned long long size) · 88 unmodified lines
962940 * peer may not initiate a resize.
963941 */
964942 /* Note these are not to be confused with
965− * drbd_adm_suspend_io/drbd_adm_resume_io,
943+ * drbd_nl_suspend_io_doit/drbd_nl_resume_io_doit,
966944 * which are (sub) state changes triggered by admin (drbdsetup),
967945 * and can be long lived.
968946 * This changes an device->flag, is triggered by drbd internals,
@@ -1574,13 +1552,14 @@ out: · 605 unmodified lines
15741552 return err;
15751553 }
15761554
1577−int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
1555+int drbd_nl_chg_disk_opts_doit(struct sk_buff *skb, struct genl_info *info)
15781556 {
15791557 struct drbd_config_context *adm_ctx = info->user_ptr[0];
15801558 enum drbd_ret_code retcode;
15811559 struct drbd_device *device;
15821560 struct disk_conf *new_disk_conf, *old_disk_conf;
15831561 struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
1562+ struct nlattr **ntb;
15841563 int err;
15851564 unsigned int fifo_size;
15861565
@@ -1612,13 +1591,29 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) · 25 unmodified lines
16121591 if (should_set_defaults(info))
16131592 set_disk_conf_defaults(new_disk_conf);
16141593
1615− err = disk_conf_from_attrs_for_change(new_disk_conf, info);
1594+ err = disk_conf_from_attrs(new_disk_conf, info);
16161595 if (err && err != -ENOMSG) {
16171596 retcode = ERR_MANDATORY_TAG;
16181597 drbd_msg_put_info(adm_ctx->reply_skb, from_attrs_err_to_txt(err));
16191598 goto fail_unlock;
16201599 }
16211600
1601+ err = disk_conf_ntb_from_attrs(&ntb, info);
1602+ if (!err) {
1603+ if (has_invariant(ntb, DRBD_A_DISK_CONF_BACKING_DEV) ||
1604+ has_invariant(ntb, DRBD_A_DISK_CONF_META_DEV) ||
1605+ has_invariant(ntb, DRBD_A_DISK_CONF_META_DEV_IDX) ||
1606+ has_invariant(ntb, DRBD_A_DISK_CONF_DISK_SIZE) ||
1607+ has_invariant(ntb, DRBD_A_DISK_CONF_MAX_BIO_BVECS)) {
1608+ retcode = ERR_MANDATORY_TAG;
1609+ drbd_msg_put_info(adm_ctx->reply_skb,
1610+ "cannot change invariant setting");
1611+ kfree(ntb);
1612+ goto fail_unlock;
1613+ }
1614+ kfree(ntb);
1615+ }
1616+
16221617 if (!expect(device, new_disk_conf->resync_rate >= 1))
16231618 new_disk_conf->resync_rate = 1;
16241619
@@ -1796,7 +1791,7 @@ void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev * · 171 unmodified lines
17961791 kfree(ldev);
17971792 }
17981793
1799−int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
1794+int drbd_nl_attach_doit(struct sk_buff *skb, struct genl_info *info)
18001795 {
18011796 struct drbd_config_context *adm_ctx = info->user_ptr[0];
18021797 struct drbd_device *device;
@@ -2236,7 +2231,7 @@ static int adm_detach(struct drbd_device *device, int force) · 433 unmodified lines
22362231 * Then we transition to D_DISKLESS, and wait for put_ldev() to return all
22372232 * internal references as well.
22382233 * Only then we have finally detached. */
2239−int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info)
2234+int drbd_nl_detach_doit(struct sk_buff *skb, struct genl_info *info)
22402235 {
22412236 struct drbd_config_context *adm_ctx = info->user_ptr[0];
22422237 enum drbd_ret_code retcode;
@@ -2434,12 +2429,13 @@ static void free_crypto(struct crypto *crypto) · 191 unmodified lines
24342429 crypto_free_shash(crypto->verify_tfm);
24352430 }
24362431
2437−int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
2432+int drbd_nl_chg_net_opts_doit(struct sk_buff *skb, struct genl_info *info)
24382433 {
24392434 struct drbd_config_context *adm_ctx = info->user_ptr[0];
24402435 enum drbd_ret_code retcode;
24412436 struct drbd_connection *connection;
24422437 struct net_conf *old_net_conf, *new_net_conf = NULL;
2438+ struct nlattr **ntb;
24432439 int err;
24442440 int ovr; /* online verify running */
24452441 int rsr; /* re-sync running */
@@ -2476,13 +2472,26 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) · 30 unmodified lines
24762472 if (should_set_defaults(info))
24772473 set_net_conf_defaults(new_net_conf);
24782474
2479− err = net_conf_from_attrs_for_change(new_net_conf, info);
2475+ err = net_conf_from_attrs(new_net_conf, info);
24802476 if (err && err != -ENOMSG) {
24812477 retcode = ERR_MANDATORY_TAG;
24822478 drbd_msg_put_info(adm_ctx->reply_skb, from_attrs_err_to_txt(err));
24832479 goto fail;
24842480 }
24852481
2482+ err = net_conf_ntb_from_attrs(&ntb, info);
2483+ if (!err) {
2484+ if (has_invariant(ntb, DRBD_A_NET_CONF_DISCARD_MY_DATA) ||
2485+ has_invariant(ntb, DRBD_A_NET_CONF_TENTATIVE)) {
2486+ retcode = ERR_MANDATORY_TAG;
2487+ drbd_msg_put_info(adm_ctx->reply_skb,
2488+ "cannot change invariant setting");
2489+ kfree(ntb);
2490+ goto fail;
2491+ }
2492+ kfree(ntb);
2493+ }
2494+
24862495 retcode = check_net_options(connection, new_net_conf);
24872496 if (retcode != NO_ERROR)
24882497 goto fail;
@@ -2575,7 +2584,7 @@ static void peer_device_to_info(struct peer_device_info *info, · 86 unmodified lines
25752584 info->peer_resync_susp_dependency = device->state.aftr_isp;
25762585 }
25772586
2578−int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
2587+int drbd_nl_connect_doit(struct sk_buff *skb, struct genl_info *info)
25792588 {
25802589 struct connection_info connection_info;
25812590 enum drbd_notification_type flags;
@@ -2790,7 +2799,7 @@ repeat: · 208 unmodified lines
27902799 return rv;
27912800 }
27922801
2793−int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info)
2802+int drbd_nl_disconnect_doit(struct sk_buff *skb, struct genl_info *info)
27942803 {
27952804 struct drbd_config_context *adm_ctx = info->user_ptr[0];
27962805 struct disconnect_parms parms;
@@ -2845,7 +2854,7 @@ void resync_after_online_grow(struct drbd_device *device) · 48 unmodified lines
28452854 _drbd_request_state(device, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE + CS_SERIALIZE);
28462855 }
28472856
2848−int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
2857+int drbd_nl_resize_doit(struct sk_buff *skb, struct genl_info *info)
28492858 {
28502859 struct drbd_config_context *adm_ctx = info->user_ptr[0];
28512860 struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
@@ -2981,7 +2990,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) · 129 unmodified lines
29812990 goto fail;
29822991 }
29832992
2984−int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
2993+int drbd_nl_resource_opts_doit(struct sk_buff *skb, struct genl_info *info)
29852994 {
29862995 struct drbd_config_context *adm_ctx = info->user_ptr[0];
29872996 enum drbd_ret_code retcode;
@@ -3019,7 +3028,7 @@ fail: · 31 unmodified lines
30193028 return 0;
30203029 }
30213030
3022−int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
3031+int drbd_nl_invalidate_doit(struct sk_buff *skb, struct genl_info *info)
30233032 {
30243033 struct drbd_config_context *adm_ctx = info->user_ptr[0];
30253034 struct drbd_device *device;
@@ -3097,7 +3106,7 @@ static int drbd_bmio_set_susp_al(struct drbd_device *device, · 71 unmodified lines
30973106 return rv;
30983107 }
30993108
3100−int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
3109+int drbd_nl_inval_peer_doit(struct sk_buff *skb, struct genl_info *info)
31013110 {
31023111 struct drbd_config_context *adm_ctx = info->user_ptr[0];
31033112 int retcode; /* drbd_ret_code, drbd_state_rv */
@@ -3148,7 +3157,7 @@ out: · 44 unmodified lines
31483157 return 0;
31493158 }
31503159
3151−int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info)
3160+int drbd_nl_pause_sync_doit(struct sk_buff *skb, struct genl_info *info)
31523161 {
31533162 struct drbd_config_context *adm_ctx = info->user_ptr[0];
31543163 enum drbd_ret_code retcode;
@@ -3168,7 +3177,7 @@ out: · 13 unmodified lines
31683177 return 0;
31693178 }
31703179
3171−int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info)
3180+int drbd_nl_resume_sync_doit(struct sk_buff *skb, struct genl_info *info)
31723181 {
31733182 struct drbd_config_context *adm_ctx = info->user_ptr[0];
31743183 union drbd_dev_state s;
@@ -3196,12 +3205,12 @@ out: · 21 unmodified lines
31963205 return 0;
31973206 }
31983207
3199−int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info)
3208+int drbd_nl_suspend_io_doit(struct sk_buff *skb, struct genl_info *info)
32003209 {
32013210 return drbd_adm_simple_request_state(skb, info, NS(susp, 1));
32023211 }
32033212
3204−int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info)
3213+int drbd_nl_resume_io_doit(struct sk_buff *skb, struct genl_info *info)
32053214 {
32063215 struct drbd_config_context *adm_ctx = info->user_ptr[0];
32073216 struct drbd_device *device;
@@ -3257,7 +3266,7 @@ out: · 49 unmodified lines
32573266 return 0;
32583267 }
32593268
3260−int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info)
3269+int drbd_nl_outdate_doit(struct sk_buff *skb, struct genl_info *info)
32613270 {
32623271 return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED));
32633272 }
@@ -3272,16 +3281,20 @@ static int nla_put_drbd_cfg_context(struct sk_buff *skb, · 8 unmodified lines
32723281 if (!nla)
32733282 goto nla_put_failure;
32743283 if (device &&
3275− nla_put_u32(skb, T_ctx_volume, device->vnr))
3284+ nla_put_u32(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME, device->vnr))
32763285 goto nla_put_failure;
3277− if (nla_put_string(skb, T_ctx_resource_name, resource->name))
3286+ if (nla_put_string(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME, resource->name))
32783287 goto nla_put_failure;
32793288 if (connection) {
32803289 if (connection->my_addr_len &&
3281− nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr))
3290+ nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR,
3291+ connection->my_addr_len,
3292+ &connection->my_addr))
32823293 goto nla_put_failure;
32833294 if (connection->peer_addr_len &&
3284− nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr))
3295+ nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR,
3296+ connection->peer_addr_len,
3297+ &connection->peer_addr))
32853298 goto nla_put_failure;
32863299 }
32873300 nla_nest_end(skb, nla);
@@ -3300,7 +3313,7 @@ nla_put_failure: · 12 unmodified lines
33003313 */
33013314 static struct nlattr *find_cfg_context_attr(const struct nlmsghdr *nlh, int attr)
33023315 {
3303− const unsigned hdrlen = GENL_HDRLEN + GENL_MAGIC_FAMILY_HDRSZ;
3316+ const unsigned int hdrlen = GENL_HDRLEN + sizeof(struct drbd_genlmsghdr);
33043317 struct nlattr *nla;
33053318
33063319 nla = nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen),
@@ -3312,7 +3325,7 @@ static struct nlattr *find_cfg_context_attr(const struct nlmsghdr *nlh, int attr · 5 unmodified lines
33123325
33133326 static void resource_to_info(struct resource_info *, struct drbd_resource *);
33143327
3315−int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb)
3328+int drbd_nl_get_resources_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
33163329 {
33173330 struct drbd_genlmsghdr *dh;
33183331 struct drbd_resource *resource;
@@ -3340,7 +3353,7 @@ found_resource: · 21 unmodified lines
33403353
33413354 put_result:
33423355 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
3343− cb->nlh->nlmsg_seq, &drbd_genl_family,
3356+ cb->nlh->nlmsg_seq, &drbd_nl_family,
33443357 NLM_F_MULTI, DRBD_ADM_GET_RESOURCES);
33453358 err = -ENOMEM;
33463359 if (!dh)
@@ -3350,15 +3363,15 @@ put_result: · 3 unmodified lines
33503363 err = nla_put_drbd_cfg_context(skb, resource, NULL, NULL);
33513364 if (err)
33523365 goto out;
3353− err = res_opts_to_skb(skb, &resource->res_opts, !capable(CAP_SYS_ADMIN));
3366+ err = res_opts_to_skb(skb, &resource->res_opts);
33543367 if (err)
33553368 goto out;
33563369 resource_to_info(&resource_info, resource);
3357− err = resource_info_to_skb(skb, &resource_info, !capable(CAP_SYS_ADMIN));
3370+ err = resource_info_to_skb(skb, &resource_info);
33583371 if (err)
33593372 goto out;
33603373 resource_statistics.res_stat_write_ordering = resource->write_ordering;
3361− err = resource_statistics_to_skb(skb, &resource_statistics, !capable(CAP_SYS_ADMIN));
3374+ err = resource_statistics_to_skb(skb, &resource_statistics);
33623375 if (err)
33633376 goto out;
33643377 cb->args[0] = (long)resource;
@@ -3423,7 +3436,7 @@ int drbd_adm_dump_devices_done(struct netlink_callback *cb) { · 58 unmodified lines
34233436
34243437 static void device_to_info(struct device_info *, struct drbd_device *);
34253438
3426−int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
3439+int drbd_nl_get_devices_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
34273440 {
34283441 struct nlattr *resource_filter;
34293442 struct drbd_resource *resource;
@@ -3436,7 +3449,8 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb) · 6 unmodified lines
34363449
34373450 resource = (struct drbd_resource *)cb->args[0];
34383451 if (!cb->args[0] && !cb->args[1]) {
3439− resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
3452+ resource_filter = find_cfg_context_attr(cb->nlh,
3453+ DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
34403454 if (resource_filter) {
34413455 retcode = ERR_RES_NOT_KNOWN;
34423456 resource = drbd_find_resource(nla_data(resource_filter));
@@ -3465,7 +3479,7 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb) · 22 unmodified lines
34653479
34663480 put_result:
34673481 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
3468− cb->nlh->nlmsg_seq, &drbd_genl_family,
3482+ cb->nlh->nlmsg_seq, &drbd_nl_family,
34693483 NLM_F_MULTI, DRBD_ADM_GET_DEVICES);
34703484 err = -ENOMEM;
34713485 if (!dh)
@@ -3481,18 +3495,18 @@ put_result: · 9 unmodified lines
34813495 struct disk_conf *disk_conf =
34823496 rcu_dereference(device->ldev->disk_conf);
34833497
3484− err = disk_conf_to_skb(skb, disk_conf, !capable(CAP_SYS_ADMIN));
3498+ err = disk_conf_to_skb(skb, disk_conf);
34853499 put_ldev(device);
34863500 if (err)
34873501 goto out;
34883502 }
34893503 device_to_info(&device_info, device);
3490− err = device_info_to_skb(skb, &device_info, !capable(CAP_SYS_ADMIN));
3504+ err = device_info_to_skb(skb, &device_info);
34913505 if (err)
34923506 goto out;
34933507
34943508 device_to_statistics(&device_statistics, device);
3495− err = device_statistics_to_skb(skb, &device_statistics, !capable(CAP_SYS_ADMIN));
3509+ err = device_statistics_to_skb(skb, &device_statistics);
34963510 if (err)
34973511 goto out;
34983512 cb->args[1] = minor + 1;
@@ -3514,7 +3528,7 @@ int drbd_adm_dump_connections_done(struct netlink_callback *cb) · 15 unmodified lines
35143528
35153529 enum { SINGLE_RESOURCE, ITERATE_RESOURCES };
35163530
3517−int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb)
3531+int drbd_nl_get_connections_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
35183532 {
35193533 struct nlattr *resource_filter;
35203534 struct drbd_resource *resource = NULL, *next_resource;
@@ -3527,7 +3541,8 @@ int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb) · 6 unmodified lines
35273541 rcu_read_lock();
35283542 resource = (struct drbd_resource *)cb->args[0];
35293543 if (!cb->args[0]) {
3530− resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
3544+ resource_filter = find_cfg_context_attr(cb->nlh,
3545+ DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
35313546 if (resource_filter) {
35323547 retcode = ERR_RES_NOT_KNOWN;
35333548 resource = drbd_find_resource(nla_data(resource_filter));
@@ -3591,7 +3606,7 @@ found_resource: · 57 unmodified lines
35913606
35923607 put_result:
35933608 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
3594− cb->nlh->nlmsg_seq, &drbd_genl_family,
3609+ cb->nlh->nlmsg_seq, &drbd_nl_family,
35953610 NLM_F_MULTI, DRBD_ADM_GET_CONNECTIONS);
35963611 err = -ENOMEM;
35973612 if (!dh)
@@ -3606,16 +3621,16 @@ put_result: · 8 unmodified lines
36063621 goto out;
36073622 net_conf = rcu_dereference(connection->net_conf);
36083623 if (net_conf) {
3609− err = net_conf_to_skb(skb, net_conf, !capable(CAP_SYS_ADMIN));
3624+ err = net_conf_to_skb(skb, net_conf);
36103625 if (err)
36113626 goto out;
36123627 }
36133628 connection_to_info(&connection_info, connection);
3614− err = connection_info_to_skb(skb, &connection_info, !capable(CAP_SYS_ADMIN));
3629+ err = connection_info_to_skb(skb, &connection_info);
36153630 if (err)
36163631 goto out;
36173632 connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags);
3618− err = connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN));
3633+ err = connection_statistics_to_skb(skb, &connection_statistics);
36193634 if (err)
36203635 goto out;
36213636 cb->args[2] = (long)connection;
@@ -3676,7 +3691,7 @@ int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb) · 54 unmodified lines
36763691 return put_resource_in_arg0(cb, 9);
36773692 }
36783693
3679−int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
3694+int drbd_nl_get_peer_devices_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
36803695 {
36813696 struct nlattr *resource_filter;
36823697 struct drbd_resource *resource;
@@ -3688,7 +3703,8 @@ int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb) · 5 unmodified lines
36883703
36893704 resource = (struct drbd_resource *)cb->args[0];
36903705 if (!cb->args[0] && !cb->args[1]) {
3691− resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
3706+ resource_filter = find_cfg_context_attr(cb->nlh,
3707+ DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
36923708 if (resource_filter) {
36933709 retcode = ERR_RES_NOT_KNOWN;
36943710 resource = drbd_find_resource(nla_data(resource_filter));
@@ -3735,7 +3751,7 @@ found_peer_device: · 40 unmodified lines
37353751
37363752 put_result:
37373753 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
3738− cb->nlh->nlmsg_seq, &drbd_genl_family,
3754+ cb->nlh->nlmsg_seq, &drbd_nl_family,
37393755 NLM_F_MULTI, DRBD_ADM_GET_PEER_DEVICES);
37403756 err = -ENOMEM;
37413757 if (!dh)
@@ -3751,11 +3767,11 @@ put_result: · 9 unmodified lines
37513767 if (err)
37523768 goto out;
37533769 peer_device_to_info(&peer_device_info, peer_device);
3754− err = peer_device_info_to_skb(skb, &peer_device_info, !capable(CAP_SYS_ADMIN));
3770+ err = peer_device_info_to_skb(skb, &peer_device_info);
37553771 if (err)
37563772 goto out;
37573773 peer_device_to_statistics(&peer_device_statistics, peer_device);
3758− err = peer_device_statistics_to_skb(skb, &peer_device_statistics, !capable(CAP_SYS_ADMIN));
3774+ err = peer_device_statistics_to_skb(skb, &peer_device_statistics);
37593775 if (err)
37603776 goto out;
37613777 cb->args[1] = minor;
@@ -3795,11 +3811,11 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, · 33 unmodified lines
37953811 /* If sib != NULL, this is drbd_bcast_event, which anyone can listen
37963812 * to. So we better exclude_sensitive information.
37973813 *
3798− * If sib == NULL, this is drbd_adm_get_status, executed synchronously
3814+ * If sib == NULL, this is drbd_nl_get_status_doit, executed synchronously
37993815 * in the context of the requesting user process. Exclude sensitive
38003816 * information, unless current has superuser.
38013817 *
3802− * NOTE: for drbd_adm_get_status_all(), this is a netlink dump, and
3818+ * NOTE: for drbd_nl_get_status_dumpit(), this is a netlink dump, and
38033819 * relies on the current implementation of netlink_dump(), which
38043820 * executes the dump callback successively from netlink_recvmsg(),
38053821 * always in the context of the receiving process */
@@ -3812,7 +3828,7 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, · 6 unmodified lines
38123828 if (nla_put_drbd_cfg_context(skb, resource, the_only_connection(resource), device))
38133829 goto nla_put_failure;
38143830
3815− if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive))
3831+ if (res_opts_to_skb(skb, &device->resource->res_opts))
38163832 goto nla_put_failure;
38173833
38183834 rcu_read_lock();
@@ -3820,14 +3836,24 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, · 1 unmodified line
38203836 struct disk_conf *disk_conf;
38213837
38223838 disk_conf = rcu_dereference(device->ldev->disk_conf);
3823− err = disk_conf_to_skb(skb, disk_conf, exclude_sensitive);
3839+ err = disk_conf_to_skb(skb, disk_conf);
38243840 }
38253841 if (!err) {
38263842 struct net_conf *nc;
38273843
38283844 nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
3829− if (nc)
3830− err = net_conf_to_skb(skb, nc, exclude_sensitive);
3845+ if (nc) {
3846+ if (exclude_sensitive) {
3847+ struct net_conf nc_clean = *nc;
3848+
3849+ memset(nc_clean.shared_secret, 0,
3850+ sizeof(nc_clean.shared_secret));
3851+ nc_clean.shared_secret_len = 0;
3852+ err = net_conf_to_skb(skb, &nc_clean);
3853+ } else {
3854+ err = net_conf_to_skb(skb, nc);
3855+ }
3856+ }
38313857 }
38323858 rcu_read_unlock();
38333859 if (err)
@@ -3836,42 +3862,57 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, · 2 unmodified lines
38363862 nla = nla_nest_start_noflag(skb, DRBD_NLA_STATE_INFO);
38373863 if (!nla)
38383864 goto nla_put_failure;
3839− if (nla_put_u32(skb, T_sib_reason, sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) ||
3840− nla_put_u32(skb, T_current_state, device->state.i) ||
3841− nla_put_u64_0pad(skb, T_ed_uuid, device->ed_uuid) ||
3842− nla_put_u64_0pad(skb, T_capacity, get_capacity(device->vdisk)) ||
3843− nla_put_u64_0pad(skb, T_send_cnt, device->send_cnt) ||
3844− nla_put_u64_0pad(skb, T_recv_cnt, device->recv_cnt) ||
3845− nla_put_u64_0pad(skb, T_read_cnt, device->read_cnt) ||
3846− nla_put_u64_0pad(skb, T_writ_cnt, device->writ_cnt) ||
3847− nla_put_u64_0pad(skb, T_al_writ_cnt, device->al_writ_cnt) ||
3848− nla_put_u64_0pad(skb, T_bm_writ_cnt, device->bm_writ_cnt) ||
3849− nla_put_u32(skb, T_ap_bio_cnt, atomic_read(&device->ap_bio_cnt)) ||
3850− nla_put_u32(skb, T_ap_pending_cnt, atomic_read(&device->ap_pending_cnt)) ||
3851− nla_put_u32(skb, T_rs_pending_cnt, atomic_read(&device->rs_pending_cnt)))
3865+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_SIB_REASON,
3866+ sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) ||
3867+ nla_put_u32(skb, DRBD_A_STATE_INFO_CURRENT_STATE,
3868+ device->state.i) ||
3869+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_ED_UUID,
3870+ device->ed_uuid, 0) ||
3871+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_CAPACITY,
3872+ get_capacity(device->vdisk), 0) ||
3873+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_SEND_CNT,
3874+ device->send_cnt, 0) ||
3875+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_RECV_CNT,
3876+ device->recv_cnt, 0) ||
3877+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_READ_CNT,
3878+ device->read_cnt, 0) ||
3879+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_WRIT_CNT,
3880+ device->writ_cnt, 0) ||
3881+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_AL_WRIT_CNT,
3882+ device->al_writ_cnt, 0) ||
3883+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BM_WRIT_CNT,
3884+ device->bm_writ_cnt, 0) ||
3885+ nla_put_u32(skb, DRBD_A_STATE_INFO_AP_BIO_CNT,
3886+ atomic_read(&device->ap_bio_cnt)) ||
3887+ nla_put_u32(skb, DRBD_A_STATE_INFO_AP_PENDING_CNT,
3888+ atomic_read(&device->ap_pending_cnt)) ||
3889+ nla_put_u32(skb, DRBD_A_STATE_INFO_RS_PENDING_CNT,
3890+ atomic_read(&device->rs_pending_cnt)))
38523891 goto nla_put_failure;
38533892
38543893 if (got_ldev) {
38553894 int err;
38563895
38573896 spin_lock_irq(&device->ldev->md.uuid_lock);
3858− err = nla_put(skb, T_uuids, sizeof(si->uuids), device->ldev->md.uuid);
3897+ err = nla_put(skb, DRBD_A_STATE_INFO_UUIDS,
3898+ sizeof(si->uuids),
3899+ device->ldev->md.uuid);
38593900 spin_unlock_irq(&device->ldev->md.uuid_lock);
38603901
38613902 if (err)
38623903 goto nla_put_failure;
38633904
3864− if (nla_put_u32(skb, T_disk_flags, device->ldev->md.flags) ||
3865− nla_put_u64_0pad(skb, T_bits_total, drbd_bm_bits(device)) ||
3866− nla_put_u64_0pad(skb, T_bits_oos,
3867− drbd_bm_total_weight(device)))
3905+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_DISK_FLAGS, device->ldev->md.flags) ||
3906+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_TOTAL, drbd_bm_bits(device), 0) ||
3907+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_OOS,
3908+ drbd_bm_total_weight(device), 0))
38683909 goto nla_put_failure;
38693910 if (C_SYNC_SOURCE <= device->state.conn &&
38703911 C_PAUSED_SYNC_T >= device->state.conn) {
3871− if (nla_put_u64_0pad(skb, T_bits_rs_total,
3872− device->rs_total) ||
3873− nla_put_u64_0pad(skb, T_bits_rs_failed,
3874− device->rs_failed))
3912+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_RS_TOTAL,
3913+ device->rs_total, 0) ||
3914+ nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_RS_FAILED,
3915+ device->rs_failed, 0))
38753916 goto nla_put_failure;
38763917 }
38773918 }
@@ -3882,17 +3923,17 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device, · 4 unmodified lines
38823923 case SIB_GET_STATUS_REPLY:
38833924 break;
38843925 case SIB_STATE_CHANGE:
3885− if (nla_put_u32(skb, T_prev_state, sib->os.i) ||
3886− nla_put_u32(skb, T_new_state, sib->ns.i))
3926+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_PREV_STATE, sib->os.i) ||
3927+ nla_put_u32(skb, DRBD_A_STATE_INFO_NEW_STATE, sib->ns.i))
38873928 goto nla_put_failure;
38883929 break;
38893930 case SIB_HELPER_POST:
3890− if (nla_put_u32(skb, T_helper_exit_code,
3931+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_HELPER_EXIT_CODE,
38913932 sib->helper_exit_code))
38923933 goto nla_put_failure;
38933934 fallthrough;
38943935 case SIB_HELPER_PRE:
3895− if (nla_put_string(skb, T_helper, sib->helper_name))
3936+ if (nla_put_string(skb, DRBD_A_STATE_INFO_HELPER, sib->helper_name))
38963937 goto nla_put_failure;
38973938 break;
38983939 }
@@ -3907,7 +3948,7 @@ nla_put_failure: · 8 unmodified lines
39073948 return err;
39083949 }
39093950
3910−int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info)
3951+int drbd_nl_get_status_doit(struct sk_buff *skb, struct genl_info *info)
39113952 {
39123953 struct drbd_config_context *adm_ctx = info->user_ptr[0];
39133954 enum drbd_ret_code retcode;
@@ -3997,7 +4038,7 @@ next_resource: · 83 unmodified lines
39974038 }
39984039
39994040 dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
4000− cb->nlh->nlmsg_seq, &drbd_genl_family,
4041+ cb->nlh->nlmsg_seq, &drbd_nl_family,
40014042 NLM_F_MULTI, DRBD_ADM_GET_STATUS);
40024043 if (!dh)
40034044 goto out;
@@ -4017,7 +4058,7 @@ next_resource: · 13 unmodified lines
40174058 struct net_conf *nc;
40184059
40194060 nc = rcu_dereference(connection->net_conf);
4020− if (nc && net_conf_to_skb(skb, nc, 1) != 0)
4061+ if (nc && net_conf_to_skb(skb, nc) != 0)
40214062 goto cancel;
40224063 }
40234064 goto done;
@@ -4059,9 +4100,9 @@ out: · 35 unmodified lines
40594100 *
40604101 * Once things are setup properly, we call into get_one_status().
40614102 */
4062−int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
4103+int drbd_nl_get_status_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
40634104 {
4064− const unsigned hdrlen = GENL_HDRLEN + GENL_MAGIC_FAMILY_HDRSZ;
4105+ const unsigned int hdrlen = GENL_HDRLEN + sizeof(struct drbd_genlmsghdr);
40654106 struct nlattr *nla;
40664107 const char *resource_name;
40674108 struct drbd_resource *resource;
@@ -4084,7 +4125,7 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb) · 16 unmodified lines
40844125 /* No explicit context given. Dump all. */
40854126 if (!nla)
40864127 goto dump;
4087− nla = nla_find_nested(nla, T_ctx_resource_name);
4128+ nla = nla_find_nested(nla, DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
40884129 /* context given, but no name present? */
40894130 if (!nla)
40904131 return -EINVAL;
@@ -4107,7 +4148,7 @@ dump: · 16 unmodified lines
41074148 return get_one_status(skb, cb);
41084149 }
41094150
4110−int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info)
4151+int drbd_nl_get_timeout_type_doit(struct sk_buff *skb, struct genl_info *info)
41114152 {
41124153 struct drbd_config_context *adm_ctx = info->user_ptr[0];
41134154 enum drbd_ret_code retcode;
@@ -4125,7 +4166,7 @@ int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info) · 11 unmodified lines
41254166 test_bit(USE_DEGR_WFC_T, &adm_ctx->device->flags) ? UT_DEGRADED :
41264167 UT_DEFAULT;
41274168
4128− err = timeout_parms_to_priv_skb(adm_ctx->reply_skb, &tp);
4169+ err = timeout_parms_to_skb(adm_ctx->reply_skb, &tp);
41294170 if (err) {
41304171 nlmsg_free(adm_ctx->reply_skb);
41314172 adm_ctx->reply_skb = NULL;
@@ -4136,7 +4177,7 @@ out: · 4 unmodified lines
41364177 return 0;
41374178 }
41384179
4139−int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
4180+int drbd_nl_start_ov_doit(struct sk_buff *skb, struct genl_info *info)
41404181 {
41414182 struct drbd_config_context *adm_ctx = info->user_ptr[0];
41424183 struct drbd_device *device;
@@ -4182,7 +4223,7 @@ out: · 39 unmodified lines
41824223 }
41834224
41844225
4185−int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
4226+int drbd_nl_new_c_uuid_doit(struct sk_buff *skb, struct genl_info *info)
41864227 {
41874228 struct drbd_config_context *adm_ctx = info->user_ptr[0];
41884229 struct drbd_device *device;
@@ -4285,7 +4326,7 @@ static void resource_to_info(struct resource_info *info, · 96 unmodified lines
42854326 info->res_susp_fen = resource->susp_fen;
42864327 }
42874328
4288−int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
4329+int drbd_nl_new_resource_doit(struct sk_buff *skb, struct genl_info *info)
42894330 {
42904331 struct drbd_connection *connection;
42914332 struct drbd_config_context *adm_ctx = info->user_ptr[0];
@@ -4348,7 +4389,7 @@ static void device_to_info(struct device_info *info, · 56 unmodified lines
43484389 }
43494390
43504391
4351−int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info)
4392+int drbd_nl_new_minor_doit(struct sk_buff *skb, struct genl_info *info)
43524393 {
43534394 struct drbd_config_context *adm_ctx = info->user_ptr[0];
43544395 struct drbd_genlmsghdr *dh = genl_info_userhdr(info);
@@ -4455,7 +4496,7 @@ static enum drbd_ret_code adm_del_minor(struct drbd_device *device) · 100 unmodified lines
44554496 return ERR_MINOR_CONFIGURED;
44564497 }
44574498
4458−int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info)
4499+int drbd_nl_del_minor_doit(struct sk_buff *skb, struct genl_info *info)
44594500 {
44604501 struct drbd_config_context *adm_ctx = info->user_ptr[0];
44614502 enum drbd_ret_code retcode;
@@ -4504,7 +4545,7 @@ static int adm_del_resource(struct drbd_resource *resource) · 42 unmodified lines
45044545 return NO_ERROR;
45054546 }
45064547
4507−int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
4548+int drbd_nl_down_doit(struct sk_buff *skb, struct genl_info *info)
45084549 {
45094550 struct drbd_config_context *adm_ctx = info->user_ptr[0];
45104551 struct drbd_resource *resource;
@@ -4567,7 +4608,7 @@ finish: · 56 unmodified lines
45674608 return 0;
45684609 }
45694610
4570−int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info)
4611+int drbd_nl_del_resource_doit(struct sk_buff *skb, struct genl_info *info)
45714612 {
45724613 struct drbd_config_context *adm_ctx = info->user_ptr[0];
45734614 struct drbd_resource *resource;
@@ -4601,7 +4642,7 @@ void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib) · 27 unmodified lines
46014642 goto failed;
46024643
46034644 err = -EMSGSIZE;
4604− d_out = genlmsg_put(msg, 0, seq, &drbd_genl_family, 0, DRBD_EVENT);
4645+ d_out = genlmsg_put(msg, 0, seq, &drbd_nl_family, 0, DRBD_ADM_EVENT);
46054646 if (!d_out) /* cannot happen, but anyways. */
46064647 goto nla_put_failure;
46074648 d_out->minor = device_to_minor(device);
@@ -4632,7 +4673,7 @@ static int nla_put_notification_header(struct sk_buff *msg, · 24 unmodified lines
46324673 .nh_type = type,
46334674 };
46344675
4635− return drbd_notification_header_to_skb(msg, &nh, true);
4676+ return drbd_notification_header_to_skb(msg, &nh);
46364677 }
46374678
46384679 int notify_resource_state(struct sk_buff *skb,
@@ -4656,7 +4697,7 @@ int notify_resource_state(struct sk_buff *skb, · 17 unmodified lines
46564697 }
46574698
46584699 err = -EMSGSIZE;
4659− dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_RESOURCE_STATE);
4700+ dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_RESOURCE_STATE);
46604701 if (!dh)
46614702 goto nla_put_failure;
46624703 dh->minor = -1U;
@@ -4664,10 +4705,10 @@ int notify_resource_state(struct sk_buff *skb, · 1 unmodified line
46644705 if (nla_put_drbd_cfg_context(skb, resource, NULL, NULL) ||
46654706 nla_put_notification_header(skb, type) ||
46664707 ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
4667− resource_info_to_skb(skb, resource_info, true)))
4708+ resource_info_to_skb(skb, resource_info)))
46684709 goto nla_put_failure;
46694710 resource_statistics.res_stat_write_ordering = resource->write_ordering;
4670− err = resource_statistics_to_skb(skb, &resource_statistics, !capable(CAP_SYS_ADMIN));
4711+ err = resource_statistics_to_skb(skb, &resource_statistics);
46714712 if (err)
46724713 goto nla_put_failure;
46734714 genlmsg_end(skb, dh);
@@ -4708,7 +4749,7 @@ int notify_device_state(struct sk_buff *skb, · 34 unmodified lines
47084749 }
47094750
47104751 err = -EMSGSIZE;
4711− dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_DEVICE_STATE);
4752+ dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_DEVICE_STATE);
47124753 if (!dh)
47134754 goto nla_put_failure;
47144755 dh->minor = device->minor;
@@ -4716,10 +4757,10 @@ int notify_device_state(struct sk_buff *skb, · 1 unmodified line
47164757 if (nla_put_drbd_cfg_context(skb, device->resource, NULL, device) ||
47174758 nla_put_notification_header(skb, type) ||
47184759 ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
4719− device_info_to_skb(skb, device_info, true)))
4760+ device_info_to_skb(skb, device_info)))
47204761 goto nla_put_failure;
47214762 device_to_statistics(&device_statistics, device);
4722− device_statistics_to_skb(skb, &device_statistics, !capable(CAP_SYS_ADMIN));
4763+ device_statistics_to_skb(skb, &device_statistics);
47234764 genlmsg_end(skb, dh);
47244765 if (multicast) {
47254766 err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
@@ -4758,7 +4799,7 @@ int notify_connection_state(struct sk_buff *skb, · 32 unmodified lines
47584799 }
47594800
47604801 err = -EMSGSIZE;
4761− dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_CONNECTION_STATE);
4802+ dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_CONNECTION_STATE);
47624803 if (!dh)
47634804 goto nla_put_failure;
47644805 dh->minor = -1U;
@@ -4766,10 +4807,10 @@ int notify_connection_state(struct sk_buff *skb, · 1 unmodified line
47664807 if (nla_put_drbd_cfg_context(skb, connection->resource, connection, NULL) ||
47674808 nla_put_notification_header(skb, type) ||
47684809 ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
4769− connection_info_to_skb(skb, connection_info, true)))
4810+ connection_info_to_skb(skb, connection_info)))
47704811 goto nla_put_failure;
47714812 connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags);
4772− connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN));
4813+ connection_statistics_to_skb(skb, &connection_statistics);
47734814 genlmsg_end(skb, dh);
47744815 if (multicast) {
47754816 err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
@@ -4809,7 +4850,7 @@ int notify_peer_device_state(struct sk_buff *skb, · 33 unmodified lines
48094850 }
48104851
48114852 err = -EMSGSIZE;
4812− dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_PEER_DEVICE_STATE);
4853+ dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_PEER_DEVICE_STATE);
48134854 if (!dh)
48144855 goto nla_put_failure;
48154856 dh->minor = -1U;
@@ -4817,10 +4858,10 @@ int notify_peer_device_state(struct sk_buff *skb, · 1 unmodified line
48174858 if (nla_put_drbd_cfg_context(skb, resource, peer_device->connection, peer_device->device) ||
48184859 nla_put_notification_header(skb, type) ||
48194860 ((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
4820− peer_device_info_to_skb(skb, peer_device_info, true)))
4861+ peer_device_info_to_skb(skb, peer_device_info)))
48214862 goto nla_put_failure;
48224863 peer_device_to_statistics(&peer_device_statistics, peer_device);
4823− peer_device_statistics_to_skb(skb, &peer_device_statistics, !capable(CAP_SYS_ADMIN));
4864+ peer_device_statistics_to_skb(skb, &peer_device_statistics);
48244865 genlmsg_end(skb, dh);
48254866 if (multicast) {
48264867 err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
@@ -4859,7 +4900,7 @@ void notify_helper(enum drbd_notification_type type, · 32 unmodified lines
48594900 goto fail;
48604901
48614902 err = -EMSGSIZE;
4862− dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_HELPER);
4903+ dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_HELPER);
48634904 if (!dh)
48644905 goto fail;
48654906 dh->minor = device ? device->minor : -1;
@@ -4867,7 +4908,7 @@ void notify_helper(enum drbd_notification_type type, · 1 unmodified line
48674908 mutex_lock(&notification_mutex);
48684909 if (nla_put_drbd_cfg_context(skb, resource, connection, device) ||
48694910 nla_put_notification_header(skb, type) ||
4870− drbd_helper_info_to_skb(skb, &helper_info, true))
4911+ drbd_helper_info_to_skb(skb, &helper_info))
48714912 goto unlock_fail;
48724913 genlmsg_end(skb, dh);
48734914 err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
@@ -4892,7 +4933,7 @@ static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq) · 18 unmodified lines
48924933 int err;
48934934
48944935 err = -EMSGSIZE;
4895− dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_INITIAL_STATE_DONE);
4936+ dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_INITIAL_STATE_DONE);
48964937 if (!dh)
48974938 goto nla_put_failure;
48984939 dh->minor = -1U;
@@ -4987,7 +5028,7 @@ out: · 88 unmodified lines
49875028 return skb->len;
49885029 }
49895030
4990−int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
5031+int drbd_nl_get_initial_state_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
49915032 {
49925033 struct drbd_resource *resource;
49935034 LIST_HEAD(head);
@@ -5035,3 +5076,20 @@ int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) · 41 unmodified lines
50355076 cb->args[2] = cb->nlh->nlmsg_seq;
50365077 return get_initial_state(skb, cb);
50375078 }
5079+
5080+static const struct genl_multicast_group drbd_nl_mcgrps[] = {
5081+ [DRBD_NLGRP_EVENTS] = { .name = "events", },
5082+};
5083+
5084+struct genl_family drbd_nl_family __ro_after_init = {
5085+ .name = "drbd",
5086+ .version = DRBD_FAMILY_VERSION,
5087+ .hdrsize = NLA_ALIGN(sizeof(struct drbd_genlmsghdr)),
5088+ .split_ops = drbd_nl_ops,
5089+ .n_split_ops = ARRAY_SIZE(drbd_nl_ops),
5090+ .mcgrps = drbd_nl_mcgrps,
5091+ .n_mcgrps = ARRAY_SIZE(drbd_nl_mcgrps),
5092+ .resv_start_op = 42,
5093+ .module = THIS_MODULE,
5094+ .netnsok = true,
5095+};
drivers/block/drbd/drbd_nl_gen.c+2606−0
@@ -0,0 +1,2606 @@
1+// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2+
3+#include <net/netlink.h>
4+#include <net/genetlink.h>
5+
6+#include <linux/kernel.h>
7+#include <linux/slab.h>
8+#include "drbd_nl_gen.h"
9+
10+#include <uapi/linux/drbd_genl.h>
11+#include <linux/drbd.h>
12+#include <linux/drbd_limits.h>
13+
14+/* Common nested types */
15+const struct nla_policy drbd_connection_info_nl_policy[DRBD_A_CONNECTION_INFO_CONN_ROLE + 1] = {
16+ [DRBD_A_CONNECTION_INFO_CONN_CONNECTION_STATE] = { .type = NLA_U32, },
17+ [DRBD_A_CONNECTION_INFO_CONN_ROLE] = { .type = NLA_U32, },
18+};
19+
20+const struct nla_policy drbd_connection_statistics_nl_policy[DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED + 1] = {
21+ [DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED] = { .type = NLA_U8, },
22+};
23+
24+const struct nla_policy drbd_detach_parms_nl_policy[DRBD_A_DETACH_PARMS_FORCE_DETACH + 1] = {
25+ [DRBD_A_DETACH_PARMS_FORCE_DETACH] = { .type = NLA_U8, },
26+};
27+
28+const struct nla_policy drbd_device_info_nl_policy[DRBD_A_DEVICE_INFO_DEV_DISK_STATE + 1] = {
29+ [DRBD_A_DEVICE_INFO_DEV_DISK_STATE] = { .type = NLA_U32, },
30+};
31+
32+const struct nla_policy drbd_device_statistics_nl_policy[DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS + 1] = {
33+ [DRBD_A_DEVICE_STATISTICS_DEV_SIZE] = { .type = NLA_U64, },
34+ [DRBD_A_DEVICE_STATISTICS_DEV_READ] = { .type = NLA_U64, },
35+ [DRBD_A_DEVICE_STATISTICS_DEV_WRITE] = { .type = NLA_U64, },
36+ [DRBD_A_DEVICE_STATISTICS_DEV_AL_WRITES] = { .type = NLA_U64, },
37+ [DRBD_A_DEVICE_STATISTICS_DEV_BM_WRITES] = { .type = NLA_U64, },
38+ [DRBD_A_DEVICE_STATISTICS_DEV_UPPER_PENDING] = { .type = NLA_U32, },
39+ [DRBD_A_DEVICE_STATISTICS_DEV_LOWER_PENDING] = { .type = NLA_U32, },
40+ [DRBD_A_DEVICE_STATISTICS_DEV_UPPER_BLOCKED] = { .type = NLA_U8, },
41+ [DRBD_A_DEVICE_STATISTICS_DEV_LOWER_BLOCKED] = { .type = NLA_U8, },
42+ [DRBD_A_DEVICE_STATISTICS_DEV_AL_SUSPENDED] = { .type = NLA_U8, },
43+ [DRBD_A_DEVICE_STATISTICS_DEV_EXPOSED_DATA_UUID] = { .type = NLA_U64, },
44+ [DRBD_A_DEVICE_STATISTICS_DEV_CURRENT_UUID] = { .type = NLA_U64, },
45+ [DRBD_A_DEVICE_STATISTICS_DEV_DISK_FLAGS] = { .type = NLA_U32, },
46+ [DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS] = NLA_POLICY_MAX_LEN(DRBD_NL_HISTORY_UUIDS_SIZE),
47+};
48+
49+const struct nla_policy drbd_disconnect_parms_nl_policy[DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT + 1] = {
50+ [DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT] = { .type = NLA_U8, },
51+};
52+
53+const struct nla_policy drbd_disk_conf_nl_policy[DRBD_A_DISK_CONF_DISABLE_WRITE_SAME + 1] = {
54+ [DRBD_A_DISK_CONF_BACKING_DEV] = { .type = NLA_NUL_STRING, .len = 128, },
55+ [DRBD_A_DISK_CONF_META_DEV] = { .type = NLA_NUL_STRING, .len = 128, },
56+ [DRBD_A_DISK_CONF_META_DEV_IDX] = { .type = NLA_U32, },
57+ [DRBD_A_DISK_CONF_DISK_SIZE] = { .type = NLA_U64, },
58+ [DRBD_A_DISK_CONF_MAX_BIO_BVECS] = { .type = NLA_U32, },
59+ [DRBD_A_DISK_CONF_ON_IO_ERROR] = { .type = NLA_U32, },
60+ [DRBD_A_DISK_CONF_FENCING] = { .type = NLA_U32, },
61+ [DRBD_A_DISK_CONF_RESYNC_RATE] = { .type = NLA_U32, },
62+ [DRBD_A_DISK_CONF_RESYNC_AFTER] = { .type = NLA_U32, },
63+ [DRBD_A_DISK_CONF_AL_EXTENTS] = { .type = NLA_U32, },
64+ [DRBD_A_DISK_CONF_C_PLAN_AHEAD] = { .type = NLA_U32, },
65+ [DRBD_A_DISK_CONF_C_DELAY_TARGET] = { .type = NLA_U32, },
66+ [DRBD_A_DISK_CONF_C_FILL_TARGET] = { .type = NLA_U32, },
67+ [DRBD_A_DISK_CONF_C_MAX_RATE] = { .type = NLA_U32, },
68+ [DRBD_A_DISK_CONF_C_MIN_RATE] = { .type = NLA_U32, },
69+ [DRBD_A_DISK_CONF_DISK_BARRIER] = { .type = NLA_U8, },
70+ [DRBD_A_DISK_CONF_DISK_FLUSHES] = { .type = NLA_U8, },
71+ [DRBD_A_DISK_CONF_DISK_DRAIN] = { .type = NLA_U8, },
72+ [DRBD_A_DISK_CONF_MD_FLUSHES] = { .type = NLA_U8, },
73+ [DRBD_A_DISK_CONF_DISK_TIMEOUT] = { .type = NLA_U32, },
74+ [DRBD_A_DISK_CONF_READ_BALANCING] = { .type = NLA_U32, },
75+ [DRBD_A_DISK_CONF_AL_UPDATES] = { .type = NLA_U8, },
76+ [DRBD_A_DISK_CONF_DISCARD_ZEROES_IF_ALIGNED] = { .type = NLA_U8, },
77+ [DRBD_A_DISK_CONF_RS_DISCARD_GRANULARITY] = { .type = NLA_U32, },
78+ [DRBD_A_DISK_CONF_DISABLE_WRITE_SAME] = { .type = NLA_U8, },
79+};
80+
81+const struct nla_policy drbd_drbd_cfg_context_nl_policy[DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR + 1] = {
82+ [DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME] = { .type = NLA_U32, },
83+ [DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME] = { .type = NLA_NUL_STRING, .len = 128, },
84+ [DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR] = NLA_POLICY_MAX_LEN(128),
85+ [DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR] = NLA_POLICY_MAX_LEN(128),
86+};
87+
88+const struct nla_policy drbd_net_conf_nl_policy[DRBD_A_NET_CONF_SOCK_CHECK_TIMEO + 1] = {
89+ [DRBD_A_NET_CONF_SHARED_SECRET] = { .type = NLA_NUL_STRING, .len = SHARED_SECRET_MAX, },
90+ [DRBD_A_NET_CONF_CRAM_HMAC_ALG] = { .type = NLA_NUL_STRING, .len = SHARED_SECRET_MAX, },
91+ [DRBD_A_NET_CONF_INTEGRITY_ALG] = { .type = NLA_NUL_STRING, .len = SHARED_SECRET_MAX, },
92+ [DRBD_A_NET_CONF_VERIFY_ALG] = { .type = NLA_NUL_STRING, .len = SHARED_SECRET_MAX, },
93+ [DRBD_A_NET_CONF_CSUMS_ALG] = { .type = NLA_NUL_STRING, .len = SHARED_SECRET_MAX, },
94+ [DRBD_A_NET_CONF_WIRE_PROTOCOL] = { .type = NLA_U32, },
95+ [DRBD_A_NET_CONF_CONNECT_INT] = { .type = NLA_U32, },
96+ [DRBD_A_NET_CONF_TIMEOUT] = { .type = NLA_U32, },
97+ [DRBD_A_NET_CONF_PING_INT] = { .type = NLA_U32, },
98+ [DRBD_A_NET_CONF_PING_TIMEO] = { .type = NLA_U32, },
99+ [DRBD_A_NET_CONF_SNDBUF_SIZE] = { .type = NLA_U32, },
100+ [DRBD_A_NET_CONF_RCVBUF_SIZE] = { .type = NLA_U32, },
101+ [DRBD_A_NET_CONF_KO_COUNT] = { .type = NLA_U32, },
102+ [DRBD_A_NET_CONF_MAX_BUFFERS] = { .type = NLA_U32, },
103+ [DRBD_A_NET_CONF_MAX_EPOCH_SIZE] = { .type = NLA_U32, },
104+ [DRBD_A_NET_CONF_UNPLUG_WATERMARK] = { .type = NLA_U32, },
105+ [DRBD_A_NET_CONF_AFTER_SB_0P] = { .type = NLA_U32, },
106+ [DRBD_A_NET_CONF_AFTER_SB_1P] = { .type = NLA_U32, },
107+ [DRBD_A_NET_CONF_AFTER_SB_2P] = { .type = NLA_U32, },
108+ [DRBD_A_NET_CONF_RR_CONFLICT] = { .type = NLA_U32, },
109+ [DRBD_A_NET_CONF_ON_CONGESTION] = { .type = NLA_U32, },
110+ [DRBD_A_NET_CONF_CONG_FILL] = { .type = NLA_U32, },
111+ [DRBD_A_NET_CONF_CONG_EXTENTS] = { .type = NLA_U32, },
112+ [DRBD_A_NET_CONF_TWO_PRIMARIES] = { .type = NLA_U8, },
113+ [DRBD_A_NET_CONF_DISCARD_MY_DATA] = { .type = NLA_U8, },
114+ [DRBD_A_NET_CONF_TCP_CORK] = { .type = NLA_U8, },
115+ [DRBD_A_NET_CONF_ALWAYS_ASBP] = { .type = NLA_U8, },
116+ [DRBD_A_NET_CONF_TENTATIVE] = { .type = NLA_U8, },
117+ [DRBD_A_NET_CONF_USE_RLE] = { .type = NLA_U8, },
118+ [DRBD_A_NET_CONF_CSUMS_AFTER_CRASH_ONLY] = { .type = NLA_U8, },
119+ [DRBD_A_NET_CONF_SOCK_CHECK_TIMEO] = { .type = NLA_U32, },
120+};
121+
122+const struct nla_policy drbd_new_c_uuid_parms_nl_policy[DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM + 1] = {
123+ [DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM] = { .type = NLA_U8, },
124+};
125+
126+const struct nla_policy drbd_peer_device_info_nl_policy[DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY + 1] = {
127+ [DRBD_A_PEER_DEVICE_INFO_PEER_REPL_STATE] = { .type = NLA_U32, },
128+ [DRBD_A_PEER_DEVICE_INFO_PEER_DISK_STATE] = { .type = NLA_U32, },
129+ [DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_USER] = { .type = NLA_U32, },
130+ [DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_PEER] = { .type = NLA_U32, },
131+ [DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY] = { .type = NLA_U32, },
132+};
133+
134+const struct nla_policy drbd_peer_device_statistics_nl_policy[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS + 1] = {
135+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RECEIVED] = { .type = NLA_U64, },
136+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_SENT] = { .type = NLA_U64, },
137+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_PENDING] = { .type = NLA_U32, },
138+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_UNACKED] = { .type = NLA_U32, },
139+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_OUT_OF_SYNC] = { .type = NLA_U64, },
140+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RESYNC_FAILED] = { .type = NLA_U64, },
141+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_BITMAP_UUID] = { .type = NLA_U64, },
142+ [DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS] = { .type = NLA_U32, },
143+};
144+
145+const struct nla_policy drbd_res_opts_nl_policy[DRBD_A_RES_OPTS_ON_NO_DATA + 1] = {
146+ [DRBD_A_RES_OPTS_CPU_MASK] = { .type = NLA_NUL_STRING, .len = DRBD_CPU_MASK_SIZE, },
147+ [DRBD_A_RES_OPTS_ON_NO_DATA] = { .type = NLA_U32, },
148+};
149+
150+const struct nla_policy drbd_resize_parms_nl_policy[DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE + 1] = {
151+ [DRBD_A_RESIZE_PARMS_RESIZE_SIZE] = { .type = NLA_U64, },
152+ [DRBD_A_RESIZE_PARMS_RESIZE_FORCE] = { .type = NLA_U8, },
153+ [DRBD_A_RESIZE_PARMS_NO_RESYNC] = { .type = NLA_U8, },
154+ [DRBD_A_RESIZE_PARMS_AL_STRIPES] = { .type = NLA_U32, },
155+ [DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE] = { .type = NLA_U32, },
156+};
157+
158+const struct nla_policy drbd_resource_info_nl_policy[DRBD_A_RESOURCE_INFO_RES_SUSP_FEN + 1] = {
159+ [DRBD_A_RESOURCE_INFO_RES_ROLE] = { .type = NLA_U32, },
160+ [DRBD_A_RESOURCE_INFO_RES_SUSP] = { .type = NLA_U8, },
161+ [DRBD_A_RESOURCE_INFO_RES_SUSP_NOD] = { .type = NLA_U8, },
162+ [DRBD_A_RESOURCE_INFO_RES_SUSP_FEN] = { .type = NLA_U8, },
163+};
164+
165+const struct nla_policy drbd_resource_statistics_nl_policy[DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING + 1] = {
166+ [DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING] = { .type = NLA_U32, },
167+};
168+
169+const struct nla_policy drbd_set_role_parms_nl_policy[DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE + 1] = {
170+ [DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE] = { .type = NLA_U8, },
171+};
172+
173+const struct nla_policy drbd_start_ov_parms_nl_policy[DRBD_A_START_OV_PARMS_OV_STOP_SECTOR + 1] = {
174+ [DRBD_A_START_OV_PARMS_OV_START_SECTOR] = { .type = NLA_U64, },
175+ [DRBD_A_START_OV_PARMS_OV_STOP_SECTOR] = { .type = NLA_U64, },
176+};
177+
178+/* DRBD_ADM_GET_STATUS - do */
179+static const struct nla_policy drbd_get_status_do_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
180+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
181+};
182+
183+/* DRBD_ADM_GET_STATUS - dump */
184+static const struct nla_policy drbd_get_status_dump_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
185+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
186+};
187+
188+/* DRBD_ADM_NEW_MINOR - do */
189+static const struct nla_policy drbd_new_minor_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
190+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
191+};
192+
193+/* DRBD_ADM_DEL_MINOR - do */
194+static const struct nla_policy drbd_del_minor_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
195+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
196+};
197+
198+/* DRBD_ADM_NEW_RESOURCE - do */
199+static const struct nla_policy drbd_new_resource_nl_policy[DRBD_NLA_RESOURCE_OPTS + 1] = {
200+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
201+ [DRBD_NLA_RESOURCE_OPTS] = NLA_POLICY_NESTED(drbd_res_opts_nl_policy),
202+};
203+
204+/* DRBD_ADM_DEL_RESOURCE - do */
205+static const struct nla_policy drbd_del_resource_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
206+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
207+};
208+
209+/* DRBD_ADM_RESOURCE_OPTS - do */
210+static const struct nla_policy drbd_resource_opts_nl_policy[DRBD_NLA_RESOURCE_OPTS + 1] = {
211+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
212+ [DRBD_NLA_RESOURCE_OPTS] = NLA_POLICY_NESTED(drbd_res_opts_nl_policy),
213+};
214+
215+/* DRBD_ADM_CONNECT - do */
216+static const struct nla_policy drbd_connect_nl_policy[DRBD_NLA_NET_CONF + 1] = {
217+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
218+ [DRBD_NLA_NET_CONF] = NLA_POLICY_NESTED(drbd_net_conf_nl_policy),
219+};
220+
221+/* DRBD_ADM_DISCONNECT - do */
222+static const struct nla_policy drbd_disconnect_nl_policy[DRBD_NLA_DISCONNECT_PARMS + 1] = {
223+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
224+ [DRBD_NLA_DISCONNECT_PARMS] = NLA_POLICY_NESTED(drbd_disconnect_parms_nl_policy),
225+};
226+
227+/* DRBD_ADM_ATTACH - do */
228+static const struct nla_policy drbd_attach_nl_policy[DRBD_NLA_DISK_CONF + 1] = {
229+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
230+ [DRBD_NLA_DISK_CONF] = NLA_POLICY_NESTED(drbd_disk_conf_nl_policy),
231+};
232+
233+/* DRBD_ADM_RESIZE - do */
234+static const struct nla_policy drbd_resize_nl_policy[DRBD_NLA_RESIZE_PARMS + 1] = {
235+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
236+ [DRBD_NLA_RESIZE_PARMS] = NLA_POLICY_NESTED(drbd_resize_parms_nl_policy),
237+};
238+
239+/* DRBD_ADM_PRIMARY - do */
240+static const struct nla_policy drbd_primary_nl_policy[DRBD_NLA_SET_ROLE_PARMS + 1] = {
241+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
242+ [DRBD_NLA_SET_ROLE_PARMS] = NLA_POLICY_NESTED(drbd_set_role_parms_nl_policy),
243+};
244+
245+/* DRBD_ADM_SECONDARY - do */
246+static const struct nla_policy drbd_secondary_nl_policy[DRBD_NLA_SET_ROLE_PARMS + 1] = {
247+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
248+ [DRBD_NLA_SET_ROLE_PARMS] = NLA_POLICY_NESTED(drbd_set_role_parms_nl_policy),
249+};
250+
251+/* DRBD_ADM_NEW_C_UUID - do */
252+static const struct nla_policy drbd_new_c_uuid_nl_policy[DRBD_NLA_NEW_C_UUID_PARMS + 1] = {
253+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
254+ [DRBD_NLA_NEW_C_UUID_PARMS] = NLA_POLICY_NESTED(drbd_new_c_uuid_parms_nl_policy),
255+};
256+
257+/* DRBD_ADM_START_OV - do */
258+static const struct nla_policy drbd_start_ov_nl_policy[DRBD_NLA_START_OV_PARMS + 1] = {
259+ [DRBD_NLA_START_OV_PARMS] = NLA_POLICY_NESTED(drbd_start_ov_parms_nl_policy),
260+};
261+
262+/* DRBD_ADM_DETACH - do */
263+static const struct nla_policy drbd_detach_nl_policy[DRBD_NLA_DETACH_PARMS + 1] = {
264+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
265+ [DRBD_NLA_DETACH_PARMS] = NLA_POLICY_NESTED(drbd_detach_parms_nl_policy),
266+};
267+
268+/* DRBD_ADM_INVALIDATE - do */
269+static const struct nla_policy drbd_invalidate_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
270+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
271+};
272+
273+/* DRBD_ADM_INVAL_PEER - do */
274+static const struct nla_policy drbd_inval_peer_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
275+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
276+};
277+
278+/* DRBD_ADM_PAUSE_SYNC - do */
279+static const struct nla_policy drbd_pause_sync_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
280+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
281+};
282+
283+/* DRBD_ADM_RESUME_SYNC - do */
284+static const struct nla_policy drbd_resume_sync_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
285+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
286+};
287+
288+/* DRBD_ADM_SUSPEND_IO - do */
289+static const struct nla_policy drbd_suspend_io_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
290+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
291+};
292+
293+/* DRBD_ADM_RESUME_IO - do */
294+static const struct nla_policy drbd_resume_io_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
295+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
296+};
297+
298+/* DRBD_ADM_OUTDATE - do */
299+static const struct nla_policy drbd_outdate_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
300+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
301+};
302+
303+/* DRBD_ADM_GET_TIMEOUT_TYPE - do */
304+static const struct nla_policy drbd_get_timeout_type_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
305+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
306+};
307+
308+/* DRBD_ADM_DOWN - do */
309+static const struct nla_policy drbd_down_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
310+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
311+};
312+
313+/* DRBD_ADM_CHG_DISK_OPTS - do */
314+static const struct nla_policy drbd_chg_disk_opts_nl_policy[DRBD_NLA_DISK_CONF + 1] = {
315+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
316+ [DRBD_NLA_DISK_CONF] = NLA_POLICY_NESTED(drbd_disk_conf_nl_policy),
317+};
318+
319+/* DRBD_ADM_CHG_NET_OPTS - do */
320+static const struct nla_policy drbd_chg_net_opts_nl_policy[DRBD_NLA_NET_CONF + 1] = {
321+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
322+ [DRBD_NLA_NET_CONF] = NLA_POLICY_NESTED(drbd_net_conf_nl_policy),
323+};
324+
325+/* DRBD_ADM_GET_RESOURCES - dump */
326+static const struct nla_policy drbd_get_resources_nl_policy[DRBD_NLA_RESOURCE_STATISTICS + 1] = {
327+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
328+ [DRBD_NLA_RESOURCE_INFO] = NLA_POLICY_NESTED(drbd_resource_info_nl_policy),
329+ [DRBD_NLA_RESOURCE_STATISTICS] = NLA_POLICY_NESTED(drbd_resource_statistics_nl_policy),
330+};
331+
332+/* DRBD_ADM_GET_DEVICES - dump */
333+static const struct nla_policy drbd_get_devices_nl_policy[DRBD_NLA_DEVICE_STATISTICS + 1] = {
334+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
335+ [DRBD_NLA_DEVICE_INFO] = NLA_POLICY_NESTED(drbd_device_info_nl_policy),
336+ [DRBD_NLA_DEVICE_STATISTICS] = NLA_POLICY_NESTED(drbd_device_statistics_nl_policy),
337+};
338+
339+/* DRBD_ADM_GET_CONNECTIONS - dump */
340+static const struct nla_policy drbd_get_connections_nl_policy[DRBD_NLA_CONNECTION_STATISTICS + 1] = {
341+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
342+ [DRBD_NLA_CONNECTION_INFO] = NLA_POLICY_NESTED(drbd_connection_info_nl_policy),
343+ [DRBD_NLA_CONNECTION_STATISTICS] = NLA_POLICY_NESTED(drbd_connection_statistics_nl_policy),
344+};
345+
346+/* DRBD_ADM_GET_PEER_DEVICES - dump */
347+static const struct nla_policy drbd_get_peer_devices_nl_policy[DRBD_NLA_PEER_DEVICE_STATISTICS + 1] = {
348+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
349+ [DRBD_NLA_PEER_DEVICE_INFO] = NLA_POLICY_NESTED(drbd_peer_device_info_nl_policy),
350+ [DRBD_NLA_PEER_DEVICE_STATISTICS] = NLA_POLICY_NESTED(drbd_peer_device_statistics_nl_policy),
351+};
352+
353+/* DRBD_ADM_GET_INITIAL_STATE - dump */
354+static const struct nla_policy drbd_get_initial_state_nl_policy[DRBD_NLA_CFG_CONTEXT + 1] = {
355+ [DRBD_NLA_CFG_CONTEXT] = NLA_POLICY_NESTED(drbd_drbd_cfg_context_nl_policy),
356+};
357+
358+/* Ops table for drbd */
359+const struct genl_split_ops drbd_nl_ops[32] = {
360+ {
361+ .cmd = DRBD_ADM_GET_STATUS,
362+ .pre_doit = drbd_pre_doit,
363+ .doit = drbd_nl_get_status_doit,
364+ .post_doit = drbd_post_doit,
365+ .policy = drbd_get_status_do_nl_policy,
366+ .maxattr = DRBD_NLA_CFG_CONTEXT,
367+ .flags = GENL_CMD_CAP_DO,
368+ },
369+ {
370+ .cmd = DRBD_ADM_GET_STATUS,
371+ .dumpit = drbd_nl_get_status_dumpit,
372+ .policy = drbd_get_status_dump_nl_policy,
373+ .maxattr = DRBD_NLA_CFG_CONTEXT,
374+ .flags = GENL_CMD_CAP_DUMP,
375+ },
376+ {
377+ .cmd = DRBD_ADM_NEW_MINOR,
378+ .pre_doit = drbd_pre_doit,
379+ .doit = drbd_nl_new_minor_doit,
380+ .post_doit = drbd_post_doit,
381+ .policy = drbd_new_minor_nl_policy,
382+ .maxattr = DRBD_NLA_CFG_CONTEXT,
383+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
384+ },
385+ {
386+ .cmd = DRBD_ADM_DEL_MINOR,
387+ .pre_doit = drbd_pre_doit,
388+ .doit = drbd_nl_del_minor_doit,
389+ .post_doit = drbd_post_doit,
390+ .policy = drbd_del_minor_nl_policy,
391+ .maxattr = DRBD_NLA_CFG_CONTEXT,
392+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
393+ },
394+ {
395+ .cmd = DRBD_ADM_NEW_RESOURCE,
396+ .pre_doit = drbd_pre_doit,
397+ .doit = drbd_nl_new_resource_doit,
398+ .post_doit = drbd_post_doit,
399+ .policy = drbd_new_resource_nl_policy,
400+ .maxattr = DRBD_NLA_RESOURCE_OPTS,
401+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
402+ },
403+ {
404+ .cmd = DRBD_ADM_DEL_RESOURCE,
405+ .pre_doit = drbd_pre_doit,
406+ .doit = drbd_nl_del_resource_doit,
407+ .post_doit = drbd_post_doit,
408+ .policy = drbd_del_resource_nl_policy,
409+ .maxattr = DRBD_NLA_CFG_CONTEXT,
410+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
411+ },
412+ {
413+ .cmd = DRBD_ADM_RESOURCE_OPTS,
414+ .pre_doit = drbd_pre_doit,
415+ .doit = drbd_nl_resource_opts_doit,
416+ .post_doit = drbd_post_doit,
417+ .policy = drbd_resource_opts_nl_policy,
418+ .maxattr = DRBD_NLA_RESOURCE_OPTS,
419+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
420+ },
421+ {
422+ .cmd = DRBD_ADM_CONNECT,
423+ .pre_doit = drbd_pre_doit,
424+ .doit = drbd_nl_connect_doit,
425+ .post_doit = drbd_post_doit,
426+ .policy = drbd_connect_nl_policy,
427+ .maxattr = DRBD_NLA_NET_CONF,
428+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
429+ },
430+ {
431+ .cmd = DRBD_ADM_DISCONNECT,
432+ .pre_doit = drbd_pre_doit,
433+ .doit = drbd_nl_disconnect_doit,
434+ .post_doit = drbd_post_doit,
435+ .policy = drbd_disconnect_nl_policy,
436+ .maxattr = DRBD_NLA_DISCONNECT_PARMS,
437+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
438+ },
439+ {
440+ .cmd = DRBD_ADM_ATTACH,
441+ .pre_doit = drbd_pre_doit,
442+ .doit = drbd_nl_attach_doit,
443+ .post_doit = drbd_post_doit,
444+ .policy = drbd_attach_nl_policy,
445+ .maxattr = DRBD_NLA_DISK_CONF,
446+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
447+ },
448+ {
449+ .cmd = DRBD_ADM_RESIZE,
450+ .pre_doit = drbd_pre_doit,
451+ .doit = drbd_nl_resize_doit,
452+ .post_doit = drbd_post_doit,
453+ .policy = drbd_resize_nl_policy,
454+ .maxattr = DRBD_NLA_RESIZE_PARMS,
455+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
456+ },
457+ {
458+ .cmd = DRBD_ADM_PRIMARY,
459+ .pre_doit = drbd_pre_doit,
460+ .doit = drbd_nl_primary_doit,
461+ .post_doit = drbd_post_doit,
462+ .policy = drbd_primary_nl_policy,
463+ .maxattr = DRBD_NLA_SET_ROLE_PARMS,
464+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
465+ },
466+ {
467+ .cmd = DRBD_ADM_SECONDARY,
468+ .pre_doit = drbd_pre_doit,
469+ .doit = drbd_nl_secondary_doit,
470+ .post_doit = drbd_post_doit,
471+ .policy = drbd_secondary_nl_policy,
472+ .maxattr = DRBD_NLA_SET_ROLE_PARMS,
473+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
474+ },
475+ {
476+ .cmd = DRBD_ADM_NEW_C_UUID,
477+ .pre_doit = drbd_pre_doit,
478+ .doit = drbd_nl_new_c_uuid_doit,
479+ .post_doit = drbd_post_doit,
480+ .policy = drbd_new_c_uuid_nl_policy,
481+ .maxattr = DRBD_NLA_NEW_C_UUID_PARMS,
482+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
483+ },
484+ {
485+ .cmd = DRBD_ADM_START_OV,
486+ .pre_doit = drbd_pre_doit,
487+ .doit = drbd_nl_start_ov_doit,
488+ .post_doit = drbd_post_doit,
489+ .policy = drbd_start_ov_nl_policy,
490+ .maxattr = DRBD_NLA_START_OV_PARMS,
491+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
492+ },
493+ {
494+ .cmd = DRBD_ADM_DETACH,
495+ .pre_doit = drbd_pre_doit,
496+ .doit = drbd_nl_detach_doit,
497+ .post_doit = drbd_post_doit,
498+ .policy = drbd_detach_nl_policy,
499+ .maxattr = DRBD_NLA_DETACH_PARMS,
500+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
501+ },
502+ {
503+ .cmd = DRBD_ADM_INVALIDATE,
504+ .pre_doit = drbd_pre_doit,
505+ .doit = drbd_nl_invalidate_doit,
506+ .post_doit = drbd_post_doit,
507+ .policy = drbd_invalidate_nl_policy,
508+ .maxattr = DRBD_NLA_CFG_CONTEXT,
509+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
510+ },
511+ {
512+ .cmd = DRBD_ADM_INVAL_PEER,
513+ .pre_doit = drbd_pre_doit,
514+ .doit = drbd_nl_inval_peer_doit,
515+ .post_doit = drbd_post_doit,
516+ .policy = drbd_inval_peer_nl_policy,
517+ .maxattr = DRBD_NLA_CFG_CONTEXT,
518+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
519+ },
520+ {
521+ .cmd = DRBD_ADM_PAUSE_SYNC,
522+ .pre_doit = drbd_pre_doit,
523+ .doit = drbd_nl_pause_sync_doit,
524+ .post_doit = drbd_post_doit,
525+ .policy = drbd_pause_sync_nl_policy,
526+ .maxattr = DRBD_NLA_CFG_CONTEXT,
527+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
528+ },
529+ {
530+ .cmd = DRBD_ADM_RESUME_SYNC,
531+ .pre_doit = drbd_pre_doit,
532+ .doit = drbd_nl_resume_sync_doit,
533+ .post_doit = drbd_post_doit,
534+ .policy = drbd_resume_sync_nl_policy,
535+ .maxattr = DRBD_NLA_CFG_CONTEXT,
536+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
537+ },
538+ {
539+ .cmd = DRBD_ADM_SUSPEND_IO,
540+ .pre_doit = drbd_pre_doit,
541+ .doit = drbd_nl_suspend_io_doit,
542+ .post_doit = drbd_post_doit,
543+ .policy = drbd_suspend_io_nl_policy,
544+ .maxattr = DRBD_NLA_CFG_CONTEXT,
545+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
546+ },
547+ {
548+ .cmd = DRBD_ADM_RESUME_IO,
549+ .pre_doit = drbd_pre_doit,
550+ .doit = drbd_nl_resume_io_doit,
551+ .post_doit = drbd_post_doit,
552+ .policy = drbd_resume_io_nl_policy,
553+ .maxattr = DRBD_NLA_CFG_CONTEXT,
554+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
555+ },
556+ {
557+ .cmd = DRBD_ADM_OUTDATE,
558+ .pre_doit = drbd_pre_doit,
559+ .doit = drbd_nl_outdate_doit,
560+ .post_doit = drbd_post_doit,
561+ .policy = drbd_outdate_nl_policy,
562+ .maxattr = DRBD_NLA_CFG_CONTEXT,
563+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
564+ },
565+ {
566+ .cmd = DRBD_ADM_GET_TIMEOUT_TYPE,
567+ .pre_doit = drbd_pre_doit,
568+ .doit = drbd_nl_get_timeout_type_doit,
569+ .post_doit = drbd_post_doit,
570+ .policy = drbd_get_timeout_type_nl_policy,
571+ .maxattr = DRBD_NLA_CFG_CONTEXT,
572+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
573+ },
574+ {
575+ .cmd = DRBD_ADM_DOWN,
576+ .pre_doit = drbd_pre_doit,
577+ .doit = drbd_nl_down_doit,
578+ .post_doit = drbd_post_doit,
579+ .policy = drbd_down_nl_policy,
580+ .maxattr = DRBD_NLA_CFG_CONTEXT,
581+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
582+ },
583+ {
584+ .cmd = DRBD_ADM_CHG_DISK_OPTS,
585+ .pre_doit = drbd_pre_doit,
586+ .doit = drbd_nl_chg_disk_opts_doit,
587+ .post_doit = drbd_post_doit,
588+ .policy = drbd_chg_disk_opts_nl_policy,
589+ .maxattr = DRBD_NLA_DISK_CONF,
590+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
591+ },
592+ {
593+ .cmd = DRBD_ADM_CHG_NET_OPTS,
594+ .pre_doit = drbd_pre_doit,
595+ .doit = drbd_nl_chg_net_opts_doit,
596+ .post_doit = drbd_post_doit,
597+ .policy = drbd_chg_net_opts_nl_policy,
598+ .maxattr = DRBD_NLA_NET_CONF,
599+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
600+ },
601+ {
602+ .cmd = DRBD_ADM_GET_RESOURCES,
603+ .dumpit = drbd_nl_get_resources_dumpit,
604+ .policy = drbd_get_resources_nl_policy,
605+ .maxattr = DRBD_NLA_RESOURCE_STATISTICS,
606+ .flags = GENL_CMD_CAP_DUMP,
607+ },
608+ {
609+ .cmd = DRBD_ADM_GET_DEVICES,
610+ .dumpit = drbd_nl_get_devices_dumpit,
611+ .done = drbd_adm_dump_devices_done,
612+ .policy = drbd_get_devices_nl_policy,
613+ .maxattr = DRBD_NLA_DEVICE_STATISTICS,
614+ .flags = GENL_CMD_CAP_DUMP,
615+ },
616+ {
617+ .cmd = DRBD_ADM_GET_CONNECTIONS,
618+ .dumpit = drbd_nl_get_connections_dumpit,
619+ .done = drbd_adm_dump_connections_done,
620+ .policy = drbd_get_connections_nl_policy,
621+ .maxattr = DRBD_NLA_CONNECTION_STATISTICS,
622+ .flags = GENL_CMD_CAP_DUMP,
623+ },
624+ {
625+ .cmd = DRBD_ADM_GET_PEER_DEVICES,
626+ .dumpit = drbd_nl_get_peer_devices_dumpit,
627+ .done = drbd_adm_dump_peer_devices_done,
628+ .policy = drbd_get_peer_devices_nl_policy,
629+ .maxattr = DRBD_NLA_PEER_DEVICE_STATISTICS,
630+ .flags = GENL_CMD_CAP_DUMP,
631+ },
632+ {
633+ .cmd = DRBD_ADM_GET_INITIAL_STATE,
634+ .dumpit = drbd_nl_get_initial_state_dumpit,
635+ .policy = drbd_get_initial_state_nl_policy,
636+ .maxattr = DRBD_NLA_CFG_CONTEXT,
637+ .flags = GENL_CMD_CAP_DUMP,
638+ },
639+};
640+
641+static const struct genl_multicast_group drbd_nl_mcgrps[] = {
642+ [DRBD_NLGRP_EVENTS] = { "events", },
643+};
644+
645+static int __drbd_cfg_context_from_attrs(struct drbd_cfg_context *s,
646+ struct nlattr ***ret_nested_attribute_table,
647+ struct genl_info *info)
648+{
649+ const int maxtype = DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR;
650+ struct nlattr *tla = info->attrs[DRBD_NLA_CFG_CONTEXT];
651+ struct nlattr **ntb;
652+ struct nlattr *nla;
653+ int err = 0;
654+
655+ if (ret_nested_attribute_table)
656+ *ret_nested_attribute_table = NULL;
657+ if (!tla)
658+ return -ENOMSG;
659+ ntb = kcalloc(DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR + 1, sizeof(*ntb), GFP_KERNEL);
660+ if (!ntb)
661+ return -ENOMEM;
662+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_drbd_cfg_context_nl_policy, NULL);
663+ if (err)
664+ goto out;
665+
666+ nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME];
667+ if (nla && s)
668+ s->ctx_volume = nla_get_u32(nla);
669+
670+ nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME];
671+ if (nla && s)
672+ s->ctx_resource_name_len = nla_strscpy(s->ctx_resource_name, nla, 128);
673+
674+ nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR];
675+ if (nla && s)
676+ s->ctx_my_addr_len = nla_memcpy(s->ctx_my_addr, nla, 128);
677+
678+ nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR];
679+ if (nla && s)
680+ s->ctx_peer_addr_len = nla_memcpy(s->ctx_peer_addr, nla, 128);
681+
682+out:
683+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
684+ *ret_nested_attribute_table = ntb;
685+ else
686+ kfree(ntb);
687+ return err;
688+}
689+
690+int drbd_cfg_context_from_attrs(struct drbd_cfg_context *s,
691+ struct genl_info *info)
692+{
693+ return __drbd_cfg_context_from_attrs(s, NULL, info);
694+}
695+
696+int drbd_cfg_context_ntb_from_attrs(
697+ struct nlattr ***ret_nested_attribute_table,
698+ struct genl_info *info)
699+{
700+ return __drbd_cfg_context_from_attrs(NULL, ret_nested_attribute_table, info);
701+}
702+
703+static int __disk_conf_from_attrs(struct disk_conf *s,
704+ struct nlattr ***ret_nested_attribute_table,
705+ struct genl_info *info)
706+{
707+ const int maxtype = DRBD_A_DISK_CONF_DISABLE_WRITE_SAME;
708+ struct nlattr *tla = info->attrs[DRBD_NLA_DISK_CONF];
709+ struct nlattr **ntb;
710+ struct nlattr *nla;
711+ int err = 0;
712+
713+ if (ret_nested_attribute_table)
714+ *ret_nested_attribute_table = NULL;
715+ if (!tla)
716+ return -ENOMSG;
717+ ntb = kcalloc(DRBD_A_DISK_CONF_DISABLE_WRITE_SAME + 1, sizeof(*ntb), GFP_KERNEL);
718+ if (!ntb)
719+ return -ENOMEM;
720+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_disk_conf_nl_policy, NULL);
721+ if (err)
722+ goto out;
723+
724+ nla = ntb[DRBD_A_DISK_CONF_BACKING_DEV];
725+ if (nla) {
726+ if (s)
727+ s->backing_dev_len = nla_strscpy(s->backing_dev, nla, 128);
728+ } else {
729+ pr_info("<< missing required attr: backing_dev\n");
730+ err = -ENOMSG;
731+ }
732+
733+ nla = ntb[DRBD_A_DISK_CONF_META_DEV];
734+ if (nla) {
735+ if (s)
736+ s->meta_dev_len = nla_strscpy(s->meta_dev, nla, 128);
737+ } else {
738+ pr_info("<< missing required attr: meta_dev\n");
739+ err = -ENOMSG;
740+ }
741+
742+ nla = ntb[DRBD_A_DISK_CONF_META_DEV_IDX];
743+ if (nla) {
744+ if (s)
745+ s->meta_dev_idx = nla_get_s32(nla);
746+ } else {
747+ pr_info("<< missing required attr: meta_dev_idx\n");
748+ err = -ENOMSG;
749+ }
750+
751+ nla = ntb[DRBD_A_DISK_CONF_DISK_SIZE];
752+ if (nla && s)
753+ s->disk_size = nla_get_u64(nla);
754+
755+ nla = ntb[DRBD_A_DISK_CONF_MAX_BIO_BVECS];
756+ if (nla && s)
757+ s->max_bio_bvecs = nla_get_u32(nla);
758+
759+ nla = ntb[DRBD_A_DISK_CONF_ON_IO_ERROR];
760+ if (nla && s)
761+ s->on_io_error = nla_get_u32(nla);
762+
763+ nla = ntb[DRBD_A_DISK_CONF_FENCING];
764+ if (nla && s)
765+ s->fencing = nla_get_u32(nla);
766+
767+ nla = ntb[DRBD_A_DISK_CONF_RESYNC_RATE];
768+ if (nla && s)
769+ s->resync_rate = nla_get_u32(nla);
770+
771+ nla = ntb[DRBD_A_DISK_CONF_RESYNC_AFTER];
772+ if (nla && s)
773+ s->resync_after = nla_get_s32(nla);
774+
775+ nla = ntb[DRBD_A_DISK_CONF_AL_EXTENTS];
776+ if (nla && s)
777+ s->al_extents = nla_get_u32(nla);
778+
779+ nla = ntb[DRBD_A_DISK_CONF_C_PLAN_AHEAD];
780+ if (nla && s)
781+ s->c_plan_ahead = nla_get_u32(nla);
782+
783+ nla = ntb[DRBD_A_DISK_CONF_C_DELAY_TARGET];
784+ if (nla && s)
785+ s->c_delay_target = nla_get_u32(nla);
786+
787+ nla = ntb[DRBD_A_DISK_CONF_C_FILL_TARGET];
788+ if (nla && s)
789+ s->c_fill_target = nla_get_u32(nla);
790+
791+ nla = ntb[DRBD_A_DISK_CONF_C_MAX_RATE];
792+ if (nla && s)
793+ s->c_max_rate = nla_get_u32(nla);
794+
795+ nla = ntb[DRBD_A_DISK_CONF_C_MIN_RATE];
796+ if (nla && s)
797+ s->c_min_rate = nla_get_u32(nla);
798+
799+ nla = ntb[DRBD_A_DISK_CONF_DISK_BARRIER];
800+ if (nla && s)
801+ s->disk_barrier = nla_get_u8(nla);
802+
803+ nla = ntb[DRBD_A_DISK_CONF_DISK_FLUSHES];
804+ if (nla && s)
805+ s->disk_flushes = nla_get_u8(nla);
806+
807+ nla = ntb[DRBD_A_DISK_CONF_DISK_DRAIN];
808+ if (nla && s)
809+ s->disk_drain = nla_get_u8(nla);
810+
811+ nla = ntb[DRBD_A_DISK_CONF_MD_FLUSHES];
812+ if (nla && s)
813+ s->md_flushes = nla_get_u8(nla);
814+
815+ nla = ntb[DRBD_A_DISK_CONF_DISK_TIMEOUT];
816+ if (nla && s)
817+ s->disk_timeout = nla_get_u32(nla);
818+
819+ nla = ntb[DRBD_A_DISK_CONF_READ_BALANCING];
820+ if (nla && s)
821+ s->read_balancing = nla_get_u32(nla);
822+
823+ nla = ntb[DRBD_A_DISK_CONF_AL_UPDATES];
824+ if (nla && s)
825+ s->al_updates = nla_get_u8(nla);
826+
827+ nla = ntb[DRBD_A_DISK_CONF_DISCARD_ZEROES_IF_ALIGNED];
828+ if (nla && s)
829+ s->discard_zeroes_if_aligned = nla_get_u8(nla);
830+
831+ nla = ntb[DRBD_A_DISK_CONF_RS_DISCARD_GRANULARITY];
832+ if (nla && s)
833+ s->rs_discard_granularity = nla_get_u32(nla);
834+
835+ nla = ntb[DRBD_A_DISK_CONF_DISABLE_WRITE_SAME];
836+ if (nla && s)
837+ s->disable_write_same = nla_get_u8(nla);
838+
839+out:
840+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
841+ *ret_nested_attribute_table = ntb;
842+ else
843+ kfree(ntb);
844+ return err;
845+}
846+
847+int disk_conf_from_attrs(struct disk_conf *s,
848+ struct genl_info *info)
849+{
850+ return __disk_conf_from_attrs(s, NULL, info);
851+}
852+
853+int disk_conf_ntb_from_attrs(
854+ struct nlattr ***ret_nested_attribute_table,
855+ struct genl_info *info)
856+{
857+ return __disk_conf_from_attrs(NULL, ret_nested_attribute_table, info);
858+}
859+
860+static int __res_opts_from_attrs(struct res_opts *s,
861+ struct nlattr ***ret_nested_attribute_table,
862+ struct genl_info *info)
863+{
864+ const int maxtype = DRBD_A_RES_OPTS_ON_NO_DATA;
865+ struct nlattr *tla = info->attrs[DRBD_NLA_RESOURCE_OPTS];
866+ struct nlattr **ntb;
867+ struct nlattr *nla;
868+ int err = 0;
869+
870+ if (ret_nested_attribute_table)
871+ *ret_nested_attribute_table = NULL;
872+ if (!tla)
873+ return -ENOMSG;
874+ ntb = kcalloc(DRBD_A_RES_OPTS_ON_NO_DATA + 1, sizeof(*ntb), GFP_KERNEL);
875+ if (!ntb)
876+ return -ENOMEM;
877+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_res_opts_nl_policy, NULL);
878+ if (err)
879+ goto out;
880+
881+ nla = ntb[DRBD_A_RES_OPTS_CPU_MASK];
882+ if (nla && s)
883+ s->cpu_mask_len = nla_strscpy(s->cpu_mask, nla, DRBD_CPU_MASK_SIZE);
884+
885+ nla = ntb[DRBD_A_RES_OPTS_ON_NO_DATA];
886+ if (nla && s)
887+ s->on_no_data = nla_get_u32(nla);
888+
889+out:
890+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
891+ *ret_nested_attribute_table = ntb;
892+ else
893+ kfree(ntb);
894+ return err;
895+}
896+
897+int res_opts_from_attrs(struct res_opts *s,
898+ struct genl_info *info)
899+{
900+ return __res_opts_from_attrs(s, NULL, info);
901+}
902+
903+int res_opts_ntb_from_attrs(
904+ struct nlattr ***ret_nested_attribute_table,
905+ struct genl_info *info)
906+{
907+ return __res_opts_from_attrs(NULL, ret_nested_attribute_table, info);
908+}
909+
910+static int __net_conf_from_attrs(struct net_conf *s,
911+ struct nlattr ***ret_nested_attribute_table,
912+ struct genl_info *info)
913+{
914+ const int maxtype = DRBD_A_NET_CONF_SOCK_CHECK_TIMEO;
915+ struct nlattr *tla = info->attrs[DRBD_NLA_NET_CONF];
916+ struct nlattr **ntb;
917+ struct nlattr *nla;
918+ int err = 0;
919+
920+ if (ret_nested_attribute_table)
921+ *ret_nested_attribute_table = NULL;
922+ if (!tla)
923+ return -ENOMSG;
924+ ntb = kcalloc(DRBD_A_NET_CONF_SOCK_CHECK_TIMEO + 1, sizeof(*ntb), GFP_KERNEL);
925+ if (!ntb)
926+ return -ENOMEM;
927+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_net_conf_nl_policy, NULL);
928+ if (err)
929+ goto out;
930+
931+ nla = ntb[DRBD_A_NET_CONF_SHARED_SECRET];
932+ if (nla && s)
933+ s->shared_secret_len = nla_strscpy(s->shared_secret, nla, SHARED_SECRET_MAX);
934+
935+ nla = ntb[DRBD_A_NET_CONF_CRAM_HMAC_ALG];
936+ if (nla && s)
937+ s->cram_hmac_alg_len = nla_strscpy(s->cram_hmac_alg, nla, SHARED_SECRET_MAX);
938+
939+ nla = ntb[DRBD_A_NET_CONF_INTEGRITY_ALG];
940+ if (nla && s)
941+ s->integrity_alg_len = nla_strscpy(s->integrity_alg, nla, SHARED_SECRET_MAX);
942+
943+ nla = ntb[DRBD_A_NET_CONF_VERIFY_ALG];
944+ if (nla && s)
945+ s->verify_alg_len = nla_strscpy(s->verify_alg, nla, SHARED_SECRET_MAX);
946+
947+ nla = ntb[DRBD_A_NET_CONF_CSUMS_ALG];
948+ if (nla && s)
949+ s->csums_alg_len = nla_strscpy(s->csums_alg, nla, SHARED_SECRET_MAX);
950+
951+ nla = ntb[DRBD_A_NET_CONF_WIRE_PROTOCOL];
952+ if (nla && s)
953+ s->wire_protocol = nla_get_u32(nla);
954+
955+ nla = ntb[DRBD_A_NET_CONF_CONNECT_INT];
956+ if (nla && s)
957+ s->connect_int = nla_get_u32(nla);
958+
959+ nla = ntb[DRBD_A_NET_CONF_TIMEOUT];
960+ if (nla && s)
961+ s->timeout = nla_get_u32(nla);
962+
963+ nla = ntb[DRBD_A_NET_CONF_PING_INT];
964+ if (nla && s)
965+ s->ping_int = nla_get_u32(nla);
966+
967+ nla = ntb[DRBD_A_NET_CONF_PING_TIMEO];
968+ if (nla && s)
969+ s->ping_timeo = nla_get_u32(nla);
970+
971+ nla = ntb[DRBD_A_NET_CONF_SNDBUF_SIZE];
972+ if (nla && s)
973+ s->sndbuf_size = nla_get_u32(nla);
974+
975+ nla = ntb[DRBD_A_NET_CONF_RCVBUF_SIZE];
976+ if (nla && s)
977+ s->rcvbuf_size = nla_get_u32(nla);
978+
979+ nla = ntb[DRBD_A_NET_CONF_KO_COUNT];
980+ if (nla && s)
981+ s->ko_count = nla_get_u32(nla);
982+
983+ nla = ntb[DRBD_A_NET_CONF_MAX_BUFFERS];
984+ if (nla && s)
985+ s->max_buffers = nla_get_u32(nla);
986+
987+ nla = ntb[DRBD_A_NET_CONF_MAX_EPOCH_SIZE];
988+ if (nla && s)
989+ s->max_epoch_size = nla_get_u32(nla);
990+
991+ nla = ntb[DRBD_A_NET_CONF_UNPLUG_WATERMARK];
992+ if (nla && s)
993+ s->unplug_watermark = nla_get_u32(nla);
994+
995+ nla = ntb[DRBD_A_NET_CONF_AFTER_SB_0P];
996+ if (nla && s)
997+ s->after_sb_0p = nla_get_u32(nla);
998+
999+ nla = ntb[DRBD_A_NET_CONF_AFTER_SB_1P];
1000+ if (nla && s)
1001+ s->after_sb_1p = nla_get_u32(nla);
1002+
1003+ nla = ntb[DRBD_A_NET_CONF_AFTER_SB_2P];
1004+ if (nla && s)
1005+ s->after_sb_2p = nla_get_u32(nla);
1006+
1007+ nla = ntb[DRBD_A_NET_CONF_RR_CONFLICT];
1008+ if (nla && s)
1009+ s->rr_conflict = nla_get_u32(nla);
1010+
1011+ nla = ntb[DRBD_A_NET_CONF_ON_CONGESTION];
1012+ if (nla && s)
1013+ s->on_congestion = nla_get_u32(nla);
1014+
1015+ nla = ntb[DRBD_A_NET_CONF_CONG_FILL];
1016+ if (nla && s)
1017+ s->cong_fill = nla_get_u32(nla);
1018+
1019+ nla = ntb[DRBD_A_NET_CONF_CONG_EXTENTS];
1020+ if (nla && s)
1021+ s->cong_extents = nla_get_u32(nla);
1022+
1023+ nla = ntb[DRBD_A_NET_CONF_TWO_PRIMARIES];
1024+ if (nla && s)
1025+ s->two_primaries = nla_get_u8(nla);
1026+
1027+ nla = ntb[DRBD_A_NET_CONF_DISCARD_MY_DATA];
1028+ if (nla && s)
1029+ s->discard_my_data = nla_get_u8(nla);
1030+
1031+ nla = ntb[DRBD_A_NET_CONF_TCP_CORK];
1032+ if (nla && s)
1033+ s->tcp_cork = nla_get_u8(nla);
1034+
1035+ nla = ntb[DRBD_A_NET_CONF_ALWAYS_ASBP];
1036+ if (nla && s)
1037+ s->always_asbp = nla_get_u8(nla);
1038+
1039+ nla = ntb[DRBD_A_NET_CONF_TENTATIVE];
1040+ if (nla && s)
1041+ s->tentative = nla_get_u8(nla);
1042+
1043+ nla = ntb[DRBD_A_NET_CONF_USE_RLE];
1044+ if (nla && s)
1045+ s->use_rle = nla_get_u8(nla);
1046+
1047+ nla = ntb[DRBD_A_NET_CONF_CSUMS_AFTER_CRASH_ONLY];
1048+ if (nla && s)
1049+ s->csums_after_crash_only = nla_get_u8(nla);
1050+
1051+ nla = ntb[DRBD_A_NET_CONF_SOCK_CHECK_TIMEO];
1052+ if (nla && s)
1053+ s->sock_check_timeo = nla_get_u32(nla);
1054+
1055+out:
1056+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1057+ *ret_nested_attribute_table = ntb;
1058+ else
1059+ kfree(ntb);
1060+ return err;
1061+}
1062+
1063+int net_conf_from_attrs(struct net_conf *s,
1064+ struct genl_info *info)
1065+{
1066+ return __net_conf_from_attrs(s, NULL, info);
1067+}
1068+
1069+int net_conf_ntb_from_attrs(
1070+ struct nlattr ***ret_nested_attribute_table,
1071+ struct genl_info *info)
1072+{
1073+ return __net_conf_from_attrs(NULL, ret_nested_attribute_table, info);
1074+}
1075+
1076+static int __set_role_parms_from_attrs(struct set_role_parms *s,
1077+ struct nlattr ***ret_nested_attribute_table,
1078+ struct genl_info *info)
1079+{
1080+ const int maxtype = DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE;
1081+ struct nlattr *tla = info->attrs[DRBD_NLA_SET_ROLE_PARMS];
1082+ struct nlattr **ntb;
1083+ struct nlattr *nla;
1084+ int err = 0;
1085+
1086+ if (ret_nested_attribute_table)
1087+ *ret_nested_attribute_table = NULL;
1088+ if (!tla)
1089+ return -ENOMSG;
1090+ ntb = kcalloc(DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE + 1, sizeof(*ntb), GFP_KERNEL);
1091+ if (!ntb)
1092+ return -ENOMEM;
1093+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_set_role_parms_nl_policy, NULL);
1094+ if (err)
1095+ goto out;
1096+
1097+ nla = ntb[DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE];
1098+ if (nla && s)
1099+ s->assume_uptodate = nla_get_u8(nla);
1100+
1101+out:
1102+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1103+ *ret_nested_attribute_table = ntb;
1104+ else
1105+ kfree(ntb);
1106+ return err;
1107+}
1108+
1109+int set_role_parms_from_attrs(struct set_role_parms *s,
1110+ struct genl_info *info)
1111+{
1112+ return __set_role_parms_from_attrs(s, NULL, info);
1113+}
1114+
1115+int set_role_parms_ntb_from_attrs(
1116+ struct nlattr ***ret_nested_attribute_table,
1117+ struct genl_info *info)
1118+{
1119+ return __set_role_parms_from_attrs(NULL, ret_nested_attribute_table, info);
1120+}
1121+
1122+static int __resize_parms_from_attrs(struct resize_parms *s,
1123+ struct nlattr ***ret_nested_attribute_table,
1124+ struct genl_info *info)
1125+{
1126+ const int maxtype = DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE;
1127+ struct nlattr *tla = info->attrs[DRBD_NLA_RESIZE_PARMS];
1128+ struct nlattr **ntb;
1129+ struct nlattr *nla;
1130+ int err = 0;
1131+
1132+ if (ret_nested_attribute_table)
1133+ *ret_nested_attribute_table = NULL;
1134+ if (!tla)
1135+ return -ENOMSG;
1136+ ntb = kcalloc(DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE + 1, sizeof(*ntb), GFP_KERNEL);
1137+ if (!ntb)
1138+ return -ENOMEM;
1139+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_resize_parms_nl_policy, NULL);
1140+ if (err)
1141+ goto out;
1142+
1143+ nla = ntb[DRBD_A_RESIZE_PARMS_RESIZE_SIZE];
1144+ if (nla && s)
1145+ s->resize_size = nla_get_u64(nla);
1146+
1147+ nla = ntb[DRBD_A_RESIZE_PARMS_RESIZE_FORCE];
1148+ if (nla && s)
1149+ s->resize_force = nla_get_u8(nla);
1150+
1151+ nla = ntb[DRBD_A_RESIZE_PARMS_NO_RESYNC];
1152+ if (nla && s)
1153+ s->no_resync = nla_get_u8(nla);
1154+
1155+ nla = ntb[DRBD_A_RESIZE_PARMS_AL_STRIPES];
1156+ if (nla && s)
1157+ s->al_stripes = nla_get_u32(nla);
1158+
1159+ nla = ntb[DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE];
1160+ if (nla && s)
1161+ s->al_stripe_size = nla_get_u32(nla);
1162+
1163+out:
1164+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1165+ *ret_nested_attribute_table = ntb;
1166+ else
1167+ kfree(ntb);
1168+ return err;
1169+}
1170+
1171+int resize_parms_from_attrs(struct resize_parms *s,
1172+ struct genl_info *info)
1173+{
1174+ return __resize_parms_from_attrs(s, NULL, info);
1175+}
1176+
1177+int resize_parms_ntb_from_attrs(
1178+ struct nlattr ***ret_nested_attribute_table,
1179+ struct genl_info *info)
1180+{
1181+ return __resize_parms_from_attrs(NULL, ret_nested_attribute_table, info);
1182+}
1183+
1184+static int __start_ov_parms_from_attrs(struct start_ov_parms *s,
1185+ struct nlattr ***ret_nested_attribute_table,
1186+ struct genl_info *info)
1187+{
1188+ const int maxtype = DRBD_A_START_OV_PARMS_OV_STOP_SECTOR;
1189+ struct nlattr *tla = info->attrs[DRBD_NLA_START_OV_PARMS];
1190+ struct nlattr **ntb;
1191+ struct nlattr *nla;
1192+ int err = 0;
1193+
1194+ if (ret_nested_attribute_table)
1195+ *ret_nested_attribute_table = NULL;
1196+ if (!tla)
1197+ return -ENOMSG;
1198+ ntb = kcalloc(DRBD_A_START_OV_PARMS_OV_STOP_SECTOR + 1, sizeof(*ntb), GFP_KERNEL);
1199+ if (!ntb)
1200+ return -ENOMEM;
1201+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_start_ov_parms_nl_policy, NULL);
1202+ if (err)
1203+ goto out;
1204+
1205+ nla = ntb[DRBD_A_START_OV_PARMS_OV_START_SECTOR];
1206+ if (nla && s)
1207+ s->ov_start_sector = nla_get_u64(nla);
1208+
1209+ nla = ntb[DRBD_A_START_OV_PARMS_OV_STOP_SECTOR];
1210+ if (nla && s)
1211+ s->ov_stop_sector = nla_get_u64(nla);
1212+
1213+out:
1214+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1215+ *ret_nested_attribute_table = ntb;
1216+ else
1217+ kfree(ntb);
1218+ return err;
1219+}
1220+
1221+int start_ov_parms_from_attrs(struct start_ov_parms *s,
1222+ struct genl_info *info)
1223+{
1224+ return __start_ov_parms_from_attrs(s, NULL, info);
1225+}
1226+
1227+int start_ov_parms_ntb_from_attrs(
1228+ struct nlattr ***ret_nested_attribute_table,
1229+ struct genl_info *info)
1230+{
1231+ return __start_ov_parms_from_attrs(NULL, ret_nested_attribute_table, info);
1232+}
1233+
1234+static int __new_c_uuid_parms_from_attrs(struct new_c_uuid_parms *s,
1235+ struct nlattr ***ret_nested_attribute_table,
1236+ struct genl_info *info)
1237+{
1238+ const int maxtype = DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM;
1239+ struct nlattr *tla = info->attrs[DRBD_NLA_NEW_C_UUID_PARMS];
1240+ struct nlattr **ntb;
1241+ struct nlattr *nla;
1242+ int err = 0;
1243+
1244+ if (ret_nested_attribute_table)
1245+ *ret_nested_attribute_table = NULL;
1246+ if (!tla)
1247+ return -ENOMSG;
1248+ ntb = kcalloc(DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM + 1, sizeof(*ntb), GFP_KERNEL);
1249+ if (!ntb)
1250+ return -ENOMEM;
1251+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_new_c_uuid_parms_nl_policy, NULL);
1252+ if (err)
1253+ goto out;
1254+
1255+ nla = ntb[DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM];
1256+ if (nla && s)
1257+ s->clear_bm = nla_get_u8(nla);
1258+
1259+out:
1260+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1261+ *ret_nested_attribute_table = ntb;
1262+ else
1263+ kfree(ntb);
1264+ return err;
1265+}
1266+
1267+int new_c_uuid_parms_from_attrs(struct new_c_uuid_parms *s,
1268+ struct genl_info *info)
1269+{
1270+ return __new_c_uuid_parms_from_attrs(s, NULL, info);
1271+}
1272+
1273+int new_c_uuid_parms_ntb_from_attrs(
1274+ struct nlattr ***ret_nested_attribute_table,
1275+ struct genl_info *info)
1276+{
1277+ return __new_c_uuid_parms_from_attrs(NULL, ret_nested_attribute_table, info);
1278+}
1279+
1280+static int __disconnect_parms_from_attrs(struct disconnect_parms *s,
1281+ struct nlattr ***ret_nested_attribute_table,
1282+ struct genl_info *info)
1283+{
1284+ const int maxtype = DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT;
1285+ struct nlattr *tla = info->attrs[DRBD_NLA_DISCONNECT_PARMS];
1286+ struct nlattr **ntb;
1287+ struct nlattr *nla;
1288+ int err = 0;
1289+
1290+ if (ret_nested_attribute_table)
1291+ *ret_nested_attribute_table = NULL;
1292+ if (!tla)
1293+ return -ENOMSG;
1294+ ntb = kcalloc(DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT + 1, sizeof(*ntb), GFP_KERNEL);
1295+ if (!ntb)
1296+ return -ENOMEM;
1297+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_disconnect_parms_nl_policy, NULL);
1298+ if (err)
1299+ goto out;
1300+
1301+ nla = ntb[DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT];
1302+ if (nla && s)
1303+ s->force_disconnect = nla_get_u8(nla);
1304+
1305+out:
1306+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1307+ *ret_nested_attribute_table = ntb;
1308+ else
1309+ kfree(ntb);
1310+ return err;
1311+}
1312+
1313+int disconnect_parms_from_attrs(struct disconnect_parms *s,
1314+ struct genl_info *info)
1315+{
1316+ return __disconnect_parms_from_attrs(s, NULL, info);
1317+}
1318+
1319+int disconnect_parms_ntb_from_attrs(
1320+ struct nlattr ***ret_nested_attribute_table,
1321+ struct genl_info *info)
1322+{
1323+ return __disconnect_parms_from_attrs(NULL, ret_nested_attribute_table, info);
1324+}
1325+
1326+static int __detach_parms_from_attrs(struct detach_parms *s,
1327+ struct nlattr ***ret_nested_attribute_table,
1328+ struct genl_info *info)
1329+{
1330+ const int maxtype = DRBD_A_DETACH_PARMS_FORCE_DETACH;
1331+ struct nlattr *tla = info->attrs[DRBD_NLA_DETACH_PARMS];
1332+ struct nlattr **ntb;
1333+ struct nlattr *nla;
1334+ int err = 0;
1335+
1336+ if (ret_nested_attribute_table)
1337+ *ret_nested_attribute_table = NULL;
1338+ if (!tla)
1339+ return -ENOMSG;
1340+ ntb = kcalloc(DRBD_A_DETACH_PARMS_FORCE_DETACH + 1, sizeof(*ntb), GFP_KERNEL);
1341+ if (!ntb)
1342+ return -ENOMEM;
1343+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_detach_parms_nl_policy, NULL);
1344+ if (err)
1345+ goto out;
1346+
1347+ nla = ntb[DRBD_A_DETACH_PARMS_FORCE_DETACH];
1348+ if (nla && s)
1349+ s->force_detach = nla_get_u8(nla);
1350+
1351+out:
1352+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1353+ *ret_nested_attribute_table = ntb;
1354+ else
1355+ kfree(ntb);
1356+ return err;
1357+}
1358+
1359+int detach_parms_from_attrs(struct detach_parms *s,
1360+ struct genl_info *info)
1361+{
1362+ return __detach_parms_from_attrs(s, NULL, info);
1363+}
1364+
1365+int detach_parms_ntb_from_attrs(
1366+ struct nlattr ***ret_nested_attribute_table,
1367+ struct genl_info *info)
1368+{
1369+ return __detach_parms_from_attrs(NULL, ret_nested_attribute_table, info);
1370+}
1371+
1372+static int __resource_info_from_attrs(struct resource_info *s,
1373+ struct nlattr ***ret_nested_attribute_table,
1374+ struct genl_info *info)
1375+{
1376+ const int maxtype = DRBD_A_RESOURCE_INFO_RES_SUSP_FEN;
1377+ struct nlattr *tla = info->attrs[DRBD_NLA_RESOURCE_INFO];
1378+ struct nlattr **ntb;
1379+ struct nlattr *nla;
1380+ int err = 0;
1381+
1382+ if (ret_nested_attribute_table)
1383+ *ret_nested_attribute_table = NULL;
1384+ if (!tla)
1385+ return -ENOMSG;
1386+ ntb = kcalloc(DRBD_A_RESOURCE_INFO_RES_SUSP_FEN + 1, sizeof(*ntb), GFP_KERNEL);
1387+ if (!ntb)
1388+ return -ENOMEM;
1389+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_resource_info_nl_policy, NULL);
1390+ if (err)
1391+ goto out;
1392+
1393+ nla = ntb[DRBD_A_RESOURCE_INFO_RES_ROLE];
1394+ if (nla && s)
1395+ s->res_role = nla_get_u32(nla);
1396+
1397+ nla = ntb[DRBD_A_RESOURCE_INFO_RES_SUSP];
1398+ if (nla && s)
1399+ s->res_susp = nla_get_u8(nla);
1400+
1401+ nla = ntb[DRBD_A_RESOURCE_INFO_RES_SUSP_NOD];
1402+ if (nla && s)
1403+ s->res_susp_nod = nla_get_u8(nla);
1404+
1405+ nla = ntb[DRBD_A_RESOURCE_INFO_RES_SUSP_FEN];
1406+ if (nla && s)
1407+ s->res_susp_fen = nla_get_u8(nla);
1408+
1409+out:
1410+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1411+ *ret_nested_attribute_table = ntb;
1412+ else
1413+ kfree(ntb);
1414+ return err;
1415+}
1416+
1417+int resource_info_from_attrs(struct resource_info *s,
1418+ struct genl_info *info)
1419+{
1420+ return __resource_info_from_attrs(s, NULL, info);
1421+}
1422+
1423+int resource_info_ntb_from_attrs(
1424+ struct nlattr ***ret_nested_attribute_table,
1425+ struct genl_info *info)
1426+{
1427+ return __resource_info_from_attrs(NULL, ret_nested_attribute_table, info);
1428+}
1429+
1430+static int __device_info_from_attrs(struct device_info *s,
1431+ struct nlattr ***ret_nested_attribute_table,
1432+ struct genl_info *info)
1433+{
1434+ const int maxtype = DRBD_A_DEVICE_INFO_DEV_DISK_STATE;
1435+ struct nlattr *tla = info->attrs[DRBD_NLA_DEVICE_INFO];
1436+ struct nlattr **ntb;
1437+ struct nlattr *nla;
1438+ int err = 0;
1439+
1440+ if (ret_nested_attribute_table)
1441+ *ret_nested_attribute_table = NULL;
1442+ if (!tla)
1443+ return -ENOMSG;
1444+ ntb = kcalloc(DRBD_A_DEVICE_INFO_DEV_DISK_STATE + 1, sizeof(*ntb), GFP_KERNEL);
1445+ if (!ntb)
1446+ return -ENOMEM;
1447+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_device_info_nl_policy, NULL);
1448+ if (err)
1449+ goto out;
1450+
1451+ nla = ntb[DRBD_A_DEVICE_INFO_DEV_DISK_STATE];
1452+ if (nla && s)
1453+ s->dev_disk_state = nla_get_u32(nla);
1454+
1455+out:
1456+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1457+ *ret_nested_attribute_table = ntb;
1458+ else
1459+ kfree(ntb);
1460+ return err;
1461+}
1462+
1463+int device_info_from_attrs(struct device_info *s,
1464+ struct genl_info *info)
1465+{
1466+ return __device_info_from_attrs(s, NULL, info);
1467+}
1468+
1469+int device_info_ntb_from_attrs(
1470+ struct nlattr ***ret_nested_attribute_table,
1471+ struct genl_info *info)
1472+{
1473+ return __device_info_from_attrs(NULL, ret_nested_attribute_table, info);
1474+}
1475+
1476+static int __connection_info_from_attrs(struct connection_info *s,
1477+ struct nlattr ***ret_nested_attribute_table,
1478+ struct genl_info *info)
1479+{
1480+ const int maxtype = DRBD_A_CONNECTION_INFO_CONN_ROLE;
1481+ struct nlattr *tla = info->attrs[DRBD_NLA_CONNECTION_INFO];
1482+ struct nlattr **ntb;
1483+ struct nlattr *nla;
1484+ int err = 0;
1485+
1486+ if (ret_nested_attribute_table)
1487+ *ret_nested_attribute_table = NULL;
1488+ if (!tla)
1489+ return -ENOMSG;
1490+ ntb = kcalloc(DRBD_A_CONNECTION_INFO_CONN_ROLE + 1, sizeof(*ntb), GFP_KERNEL);
1491+ if (!ntb)
1492+ return -ENOMEM;
1493+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_connection_info_nl_policy, NULL);
1494+ if (err)
1495+ goto out;
1496+
1497+ nla = ntb[DRBD_A_CONNECTION_INFO_CONN_CONNECTION_STATE];
1498+ if (nla && s)
1499+ s->conn_connection_state = nla_get_u32(nla);
1500+
1501+ nla = ntb[DRBD_A_CONNECTION_INFO_CONN_ROLE];
1502+ if (nla && s)
1503+ s->conn_role = nla_get_u32(nla);
1504+
1505+out:
1506+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1507+ *ret_nested_attribute_table = ntb;
1508+ else
1509+ kfree(ntb);
1510+ return err;
1511+}
1512+
1513+int connection_info_from_attrs(struct connection_info *s,
1514+ struct genl_info *info)
1515+{
1516+ return __connection_info_from_attrs(s, NULL, info);
1517+}
1518+
1519+int connection_info_ntb_from_attrs(
1520+ struct nlattr ***ret_nested_attribute_table,
1521+ struct genl_info *info)
1522+{
1523+ return __connection_info_from_attrs(NULL, ret_nested_attribute_table, info);
1524+}
1525+
1526+static int __peer_device_info_from_attrs(struct peer_device_info *s,
1527+ struct nlattr ***ret_nested_attribute_table,
1528+ struct genl_info *info)
1529+{
1530+ const int maxtype = DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY;
1531+ struct nlattr *tla = info->attrs[DRBD_NLA_PEER_DEVICE_INFO];
1532+ struct nlattr **ntb;
1533+ struct nlattr *nla;
1534+ int err = 0;
1535+
1536+ if (ret_nested_attribute_table)
1537+ *ret_nested_attribute_table = NULL;
1538+ if (!tla)
1539+ return -ENOMSG;
1540+ ntb = kcalloc(DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY + 1, sizeof(*ntb), GFP_KERNEL);
1541+ if (!ntb)
1542+ return -ENOMEM;
1543+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_peer_device_info_nl_policy, NULL);
1544+ if (err)
1545+ goto out;
1546+
1547+ nla = ntb[DRBD_A_PEER_DEVICE_INFO_PEER_REPL_STATE];
1548+ if (nla && s)
1549+ s->peer_repl_state = nla_get_u32(nla);
1550+
1551+ nla = ntb[DRBD_A_PEER_DEVICE_INFO_PEER_DISK_STATE];
1552+ if (nla && s)
1553+ s->peer_disk_state = nla_get_u32(nla);
1554+
1555+ nla = ntb[DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_USER];
1556+ if (nla && s)
1557+ s->peer_resync_susp_user = nla_get_u32(nla);
1558+
1559+ nla = ntb[DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_PEER];
1560+ if (nla && s)
1561+ s->peer_resync_susp_peer = nla_get_u32(nla);
1562+
1563+ nla = ntb[DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY];
1564+ if (nla && s)
1565+ s->peer_resync_susp_dependency = nla_get_u32(nla);
1566+
1567+out:
1568+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1569+ *ret_nested_attribute_table = ntb;
1570+ else
1571+ kfree(ntb);
1572+ return err;
1573+}
1574+
1575+int peer_device_info_from_attrs(struct peer_device_info *s,
1576+ struct genl_info *info)
1577+{
1578+ return __peer_device_info_from_attrs(s, NULL, info);
1579+}
1580+
1581+int peer_device_info_ntb_from_attrs(
1582+ struct nlattr ***ret_nested_attribute_table,
1583+ struct genl_info *info)
1584+{
1585+ return __peer_device_info_from_attrs(NULL, ret_nested_attribute_table, info);
1586+}
1587+
1588+static int __resource_statistics_from_attrs(struct resource_statistics *s,
1589+ struct nlattr ***ret_nested_attribute_table,
1590+ struct genl_info *info)
1591+{
1592+ const int maxtype = DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING;
1593+ struct nlattr *tla = info->attrs[DRBD_NLA_RESOURCE_STATISTICS];
1594+ struct nlattr **ntb;
1595+ struct nlattr *nla;
1596+ int err = 0;
1597+
1598+ if (ret_nested_attribute_table)
1599+ *ret_nested_attribute_table = NULL;
1600+ if (!tla)
1601+ return -ENOMSG;
1602+ ntb = kcalloc(DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING + 1, sizeof(*ntb), GFP_KERNEL);
1603+ if (!ntb)
1604+ return -ENOMEM;
1605+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_resource_statistics_nl_policy, NULL);
1606+ if (err)
1607+ goto out;
1608+
1609+ nla = ntb[DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING];
1610+ if (nla && s)
1611+ s->res_stat_write_ordering = nla_get_u32(nla);
1612+
1613+out:
1614+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1615+ *ret_nested_attribute_table = ntb;
1616+ else
1617+ kfree(ntb);
1618+ return err;
1619+}
1620+
1621+int resource_statistics_from_attrs(struct resource_statistics *s,
1622+ struct genl_info *info)
1623+{
1624+ return __resource_statistics_from_attrs(s, NULL, info);
1625+}
1626+
1627+int resource_statistics_ntb_from_attrs(
1628+ struct nlattr ***ret_nested_attribute_table,
1629+ struct genl_info *info)
1630+{
1631+ return __resource_statistics_from_attrs(NULL, ret_nested_attribute_table, info);
1632+}
1633+
1634+static int __device_statistics_from_attrs(struct device_statistics *s,
1635+ struct nlattr ***ret_nested_attribute_table,
1636+ struct genl_info *info)
1637+{
1638+ const int maxtype = DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS;
1639+ struct nlattr *tla = info->attrs[DRBD_NLA_DEVICE_STATISTICS];
1640+ struct nlattr **ntb;
1641+ struct nlattr *nla;
1642+ int err = 0;
1643+
1644+ if (ret_nested_attribute_table)
1645+ *ret_nested_attribute_table = NULL;
1646+ if (!tla)
1647+ return -ENOMSG;
1648+ ntb = kcalloc(DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS + 1, sizeof(*ntb), GFP_KERNEL);
1649+ if (!ntb)
1650+ return -ENOMEM;
1651+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_device_statistics_nl_policy, NULL);
1652+ if (err)
1653+ goto out;
1654+
1655+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_SIZE];
1656+ if (nla && s)
1657+ s->dev_size = nla_get_u64(nla);
1658+
1659+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_READ];
1660+ if (nla && s)
1661+ s->dev_read = nla_get_u64(nla);
1662+
1663+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_WRITE];
1664+ if (nla && s)
1665+ s->dev_write = nla_get_u64(nla);
1666+
1667+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_AL_WRITES];
1668+ if (nla && s)
1669+ s->dev_al_writes = nla_get_u64(nla);
1670+
1671+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_BM_WRITES];
1672+ if (nla && s)
1673+ s->dev_bm_writes = nla_get_u64(nla);
1674+
1675+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_UPPER_PENDING];
1676+ if (nla && s)
1677+ s->dev_upper_pending = nla_get_u32(nla);
1678+
1679+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_LOWER_PENDING];
1680+ if (nla && s)
1681+ s->dev_lower_pending = nla_get_u32(nla);
1682+
1683+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_UPPER_BLOCKED];
1684+ if (nla && s)
1685+ s->dev_upper_blocked = nla_get_u8(nla);
1686+
1687+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_LOWER_BLOCKED];
1688+ if (nla && s)
1689+ s->dev_lower_blocked = nla_get_u8(nla);
1690+
1691+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_AL_SUSPENDED];
1692+ if (nla && s)
1693+ s->dev_al_suspended = nla_get_u8(nla);
1694+
1695+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_EXPOSED_DATA_UUID];
1696+ if (nla && s)
1697+ s->dev_exposed_data_uuid = nla_get_u64(nla);
1698+
1699+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_CURRENT_UUID];
1700+ if (nla && s)
1701+ s->dev_current_uuid = nla_get_u64(nla);
1702+
1703+ nla = ntb[DRBD_A_DEVICE_STATISTICS_DEV_DISK_FLAGS];
1704+ if (nla && s)
1705+ s->dev_disk_flags = nla_get_u32(nla);
1706+
1707+ nla = ntb[DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS];
1708+ if (nla && s)
1709+ s->history_uuids_len = nla_memcpy(s->history_uuids, nla, DRBD_NL_HISTORY_UUIDS_SIZE);
1710+
1711+out:
1712+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1713+ *ret_nested_attribute_table = ntb;
1714+ else
1715+ kfree(ntb);
1716+ return err;
1717+}
1718+
1719+int device_statistics_from_attrs(struct device_statistics *s,
1720+ struct genl_info *info)
1721+{
1722+ return __device_statistics_from_attrs(s, NULL, info);
1723+}
1724+
1725+int device_statistics_ntb_from_attrs(
1726+ struct nlattr ***ret_nested_attribute_table,
1727+ struct genl_info *info)
1728+{
1729+ return __device_statistics_from_attrs(NULL, ret_nested_attribute_table, info);
1730+}
1731+
1732+static int __connection_statistics_from_attrs(struct connection_statistics *s,
1733+ struct nlattr ***ret_nested_attribute_table,
1734+ struct genl_info *info)
1735+{
1736+ const int maxtype = DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED;
1737+ struct nlattr *tla = info->attrs[DRBD_NLA_CONNECTION_STATISTICS];
1738+ struct nlattr **ntb;
1739+ struct nlattr *nla;
1740+ int err = 0;
1741+
1742+ if (ret_nested_attribute_table)
1743+ *ret_nested_attribute_table = NULL;
1744+ if (!tla)
1745+ return -ENOMSG;
1746+ ntb = kcalloc(DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED + 1, sizeof(*ntb), GFP_KERNEL);
1747+ if (!ntb)
1748+ return -ENOMEM;
1749+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_connection_statistics_nl_policy, NULL);
1750+ if (err)
1751+ goto out;
1752+
1753+ nla = ntb[DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED];
1754+ if (nla && s)
1755+ s->conn_congested = nla_get_u8(nla);
1756+
1757+out:
1758+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1759+ *ret_nested_attribute_table = ntb;
1760+ else
1761+ kfree(ntb);
1762+ return err;
1763+}
1764+
1765+int connection_statistics_from_attrs(struct connection_statistics *s,
1766+ struct genl_info *info)
1767+{
1768+ return __connection_statistics_from_attrs(s, NULL, info);
1769+}
1770+
1771+int connection_statistics_ntb_from_attrs(
1772+ struct nlattr ***ret_nested_attribute_table,
1773+ struct genl_info *info)
1774+{
1775+ return __connection_statistics_from_attrs(NULL, ret_nested_attribute_table, info);
1776+}
1777+
1778+static int __peer_device_statistics_from_attrs(struct peer_device_statistics *s,
1779+ struct nlattr ***ret_nested_attribute_table,
1780+ struct genl_info *info)
1781+{
1782+ const int maxtype = DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS;
1783+ struct nlattr *tla = info->attrs[DRBD_NLA_PEER_DEVICE_STATISTICS];
1784+ struct nlattr **ntb;
1785+ struct nlattr *nla;
1786+ int err = 0;
1787+
1788+ if (ret_nested_attribute_table)
1789+ *ret_nested_attribute_table = NULL;
1790+ if (!tla)
1791+ return -ENOMSG;
1792+ ntb = kcalloc(DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS + 1, sizeof(*ntb), GFP_KERNEL);
1793+ if (!ntb)
1794+ return -ENOMEM;
1795+ err = nla_parse_nested_deprecated(ntb, maxtype, tla, drbd_peer_device_statistics_nl_policy, NULL);
1796+ if (err)
1797+ goto out;
1798+
1799+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RECEIVED];
1800+ if (nla && s)
1801+ s->peer_dev_received = nla_get_u64(nla);
1802+
1803+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_SENT];
1804+ if (nla && s)
1805+ s->peer_dev_sent = nla_get_u64(nla);
1806+
1807+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_PENDING];
1808+ if (nla && s)
1809+ s->peer_dev_pending = nla_get_u32(nla);
1810+
1811+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_UNACKED];
1812+ if (nla && s)
1813+ s->peer_dev_unacked = nla_get_u32(nla);
1814+
1815+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_OUT_OF_SYNC];
1816+ if (nla && s)
1817+ s->peer_dev_out_of_sync = nla_get_u64(nla);
1818+
1819+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RESYNC_FAILED];
1820+ if (nla && s)
1821+ s->peer_dev_resync_failed = nla_get_u64(nla);
1822+
1823+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_BITMAP_UUID];
1824+ if (nla && s)
1825+ s->peer_dev_bitmap_uuid = nla_get_u64(nla);
1826+
1827+ nla = ntb[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS];
1828+ if (nla && s)
1829+ s->peer_dev_flags = nla_get_u32(nla);
1830+
1831+out:
1832+ if (ret_nested_attribute_table && (!err || err == -ENOMSG))
1833+ *ret_nested_attribute_table = ntb;
1834+ else
1835+ kfree(ntb);
1836+ return err;
1837+}
1838+
1839+int peer_device_statistics_from_attrs(struct peer_device_statistics *s,
1840+ struct genl_info *info)
1841+{
1842+ return __peer_device_statistics_from_attrs(s, NULL, info);
1843+}
1844+
1845+int peer_device_statistics_ntb_from_attrs(
1846+ struct nlattr ***ret_nested_attribute_table,
1847+ struct genl_info *info)
1848+{
1849+ return __peer_device_statistics_from_attrs(NULL, ret_nested_attribute_table, info);
1850+}
1851+
1852+int drbd_cfg_reply_to_skb(struct sk_buff *skb, struct drbd_cfg_reply *s)
1853+{
1854+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_CFG_REPLY);
1855+
1856+ if (!tla)
1857+ goto nla_put_failure;
1858+
1859+ if (nla_put(skb, DRBD_A_DRBD_CFG_REPLY_INFO_TEXT, min_t(int, 0,
1860+ s->info_text_len + (s->info_text_len < 0)), s->info_text))
1861+ goto nla_put_failure;
1862+
1863+ nla_nest_end(skb, tla);
1864+ return 0;
1865+
1866+nla_put_failure:
1867+ if (tla)
1868+ nla_nest_cancel(skb, tla);
1869+ return -EMSGSIZE;
1870+}
1871+
1872+int drbd_cfg_context_to_skb(struct sk_buff *skb, struct drbd_cfg_context *s)
1873+{
1874+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_CFG_CONTEXT);
1875+
1876+ if (!tla)
1877+ goto nla_put_failure;
1878+
1879+ if (nla_put_u32(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME, s->ctx_volume))
1880+ goto nla_put_failure;
1881+ if (nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME, min_t(int, 128,
1882+ s->ctx_resource_name_len + (s->ctx_resource_name_len < 128)), s->ctx_resource_name))
1883+ goto nla_put_failure;
1884+ if (nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR, min_t(int, 128,
1885+ s->ctx_my_addr_len), s->ctx_my_addr))
1886+ goto nla_put_failure;
1887+ if (nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR, min_t(int, 128,
1888+ s->ctx_peer_addr_len), s->ctx_peer_addr))
1889+ goto nla_put_failure;
1890+
1891+ nla_nest_end(skb, tla);
1892+ return 0;
1893+
1894+nla_put_failure:
1895+ if (tla)
1896+ nla_nest_cancel(skb, tla);
1897+ return -EMSGSIZE;
1898+}
1899+
1900+int disk_conf_to_skb(struct sk_buff *skb, struct disk_conf *s)
1901+{
1902+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_DISK_CONF);
1903+
1904+ if (!tla)
1905+ goto nla_put_failure;
1906+
1907+ if (nla_put(skb, DRBD_A_DISK_CONF_BACKING_DEV, min_t(int, 128,
1908+ s->backing_dev_len + (s->backing_dev_len < 128)), s->backing_dev))
1909+ goto nla_put_failure;
1910+ if (nla_put(skb, DRBD_A_DISK_CONF_META_DEV, min_t(int, 128,
1911+ s->meta_dev_len + (s->meta_dev_len < 128)), s->meta_dev))
1912+ goto nla_put_failure;
1913+ if (nla_put_s32(skb, DRBD_A_DISK_CONF_META_DEV_IDX, s->meta_dev_idx))
1914+ goto nla_put_failure;
1915+ if (nla_put_u64_64bit(skb, DRBD_A_DISK_CONF_DISK_SIZE, s->disk_size, 0))
1916+ goto nla_put_failure;
1917+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_MAX_BIO_BVECS, s->max_bio_bvecs))
1918+ goto nla_put_failure;
1919+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_ON_IO_ERROR, s->on_io_error))
1920+ goto nla_put_failure;
1921+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_FENCING, s->fencing))
1922+ goto nla_put_failure;
1923+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_RESYNC_RATE, s->resync_rate))
1924+ goto nla_put_failure;
1925+ if (nla_put_s32(skb, DRBD_A_DISK_CONF_RESYNC_AFTER, s->resync_after))
1926+ goto nla_put_failure;
1927+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_AL_EXTENTS, s->al_extents))
1928+ goto nla_put_failure;
1929+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_C_PLAN_AHEAD, s->c_plan_ahead))
1930+ goto nla_put_failure;
1931+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_C_DELAY_TARGET, s->c_delay_target))
1932+ goto nla_put_failure;
1933+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_C_FILL_TARGET, s->c_fill_target))
1934+ goto nla_put_failure;
1935+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_C_MAX_RATE, s->c_max_rate))
1936+ goto nla_put_failure;
1937+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_C_MIN_RATE, s->c_min_rate))
1938+ goto nla_put_failure;
1939+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_DISK_BARRIER, s->disk_barrier))
1940+ goto nla_put_failure;
1941+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_DISK_FLUSHES, s->disk_flushes))
1942+ goto nla_put_failure;
1943+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_DISK_DRAIN, s->disk_drain))
1944+ goto nla_put_failure;
1945+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_MD_FLUSHES, s->md_flushes))
1946+ goto nla_put_failure;
1947+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_DISK_TIMEOUT, s->disk_timeout))
1948+ goto nla_put_failure;
1949+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_READ_BALANCING, s->read_balancing))
1950+ goto nla_put_failure;
1951+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_AL_UPDATES, s->al_updates))
1952+ goto nla_put_failure;
1953+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_DISCARD_ZEROES_IF_ALIGNED, s->discard_zeroes_if_aligned))
1954+ goto nla_put_failure;
1955+ if (nla_put_u32(skb, DRBD_A_DISK_CONF_RS_DISCARD_GRANULARITY, s->rs_discard_granularity))
1956+ goto nla_put_failure;
1957+ if (nla_put_u8(skb, DRBD_A_DISK_CONF_DISABLE_WRITE_SAME, s->disable_write_same))
1958+ goto nla_put_failure;
1959+
1960+ nla_nest_end(skb, tla);
1961+ return 0;
1962+
1963+nla_put_failure:
1964+ if (tla)
1965+ nla_nest_cancel(skb, tla);
1966+ return -EMSGSIZE;
1967+}
1968+
1969+int res_opts_to_skb(struct sk_buff *skb, struct res_opts *s)
1970+{
1971+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_RESOURCE_OPTS);
1972+
1973+ if (!tla)
1974+ goto nla_put_failure;
1975+
1976+ if (nla_put(skb, DRBD_A_RES_OPTS_CPU_MASK, min_t(int, DRBD_CPU_MASK_SIZE,
1977+ s->cpu_mask_len + (s->cpu_mask_len < DRBD_CPU_MASK_SIZE)), s->cpu_mask))
1978+ goto nla_put_failure;
1979+ if (nla_put_u32(skb, DRBD_A_RES_OPTS_ON_NO_DATA, s->on_no_data))
1980+ goto nla_put_failure;
1981+
1982+ nla_nest_end(skb, tla);
1983+ return 0;
1984+
1985+nla_put_failure:
1986+ if (tla)
1987+ nla_nest_cancel(skb, tla);
1988+ return -EMSGSIZE;
1989+}
1990+
1991+int net_conf_to_skb(struct sk_buff *skb, struct net_conf *s)
1992+{
1993+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_NET_CONF);
1994+
1995+ if (!tla)
1996+ goto nla_put_failure;
1997+
1998+ if (nla_put(skb, DRBD_A_NET_CONF_SHARED_SECRET, min_t(int, SHARED_SECRET_MAX,
1999+ s->shared_secret_len + (s->shared_secret_len < SHARED_SECRET_MAX)), s->shared_secret))
2000+ goto nla_put_failure;
2001+ if (nla_put(skb, DRBD_A_NET_CONF_CRAM_HMAC_ALG, min_t(int, SHARED_SECRET_MAX,
2002+ s->cram_hmac_alg_len + (s->cram_hmac_alg_len < SHARED_SECRET_MAX)), s->cram_hmac_alg))
2003+ goto nla_put_failure;
2004+ if (nla_put(skb, DRBD_A_NET_CONF_INTEGRITY_ALG, min_t(int, SHARED_SECRET_MAX,
2005+ s->integrity_alg_len + (s->integrity_alg_len < SHARED_SECRET_MAX)), s->integrity_alg))
2006+ goto nla_put_failure;
2007+ if (nla_put(skb, DRBD_A_NET_CONF_VERIFY_ALG, min_t(int, SHARED_SECRET_MAX,
2008+ s->verify_alg_len + (s->verify_alg_len < SHARED_SECRET_MAX)), s->verify_alg))
2009+ goto nla_put_failure;
2010+ if (nla_put(skb, DRBD_A_NET_CONF_CSUMS_ALG, min_t(int, SHARED_SECRET_MAX,
2011+ s->csums_alg_len + (s->csums_alg_len < SHARED_SECRET_MAX)), s->csums_alg))
2012+ goto nla_put_failure;
2013+ if (nla_put_u32(skb, DRBD_A_NET_CONF_WIRE_PROTOCOL, s->wire_protocol))
2014+ goto nla_put_failure;
2015+ if (nla_put_u32(skb, DRBD_A_NET_CONF_CONNECT_INT, s->connect_int))
2016+ goto nla_put_failure;
2017+ if (nla_put_u32(skb, DRBD_A_NET_CONF_TIMEOUT, s->timeout))
2018+ goto nla_put_failure;
2019+ if (nla_put_u32(skb, DRBD_A_NET_CONF_PING_INT, s->ping_int))
2020+ goto nla_put_failure;
2021+ if (nla_put_u32(skb, DRBD_A_NET_CONF_PING_TIMEO, s->ping_timeo))
2022+ goto nla_put_failure;
2023+ if (nla_put_u32(skb, DRBD_A_NET_CONF_SNDBUF_SIZE, s->sndbuf_size))
2024+ goto nla_put_failure;
2025+ if (nla_put_u32(skb, DRBD_A_NET_CONF_RCVBUF_SIZE, s->rcvbuf_size))
2026+ goto nla_put_failure;
2027+ if (nla_put_u32(skb, DRBD_A_NET_CONF_KO_COUNT, s->ko_count))
2028+ goto nla_put_failure;
2029+ if (nla_put_u32(skb, DRBD_A_NET_CONF_MAX_BUFFERS, s->max_buffers))
2030+ goto nla_put_failure;
2031+ if (nla_put_u32(skb, DRBD_A_NET_CONF_MAX_EPOCH_SIZE, s->max_epoch_size))
2032+ goto nla_put_failure;
2033+ if (nla_put_u32(skb, DRBD_A_NET_CONF_UNPLUG_WATERMARK, s->unplug_watermark))
2034+ goto nla_put_failure;
2035+ if (nla_put_u32(skb, DRBD_A_NET_CONF_AFTER_SB_0P, s->after_sb_0p))
2036+ goto nla_put_failure;
2037+ if (nla_put_u32(skb, DRBD_A_NET_CONF_AFTER_SB_1P, s->after_sb_1p))
2038+ goto nla_put_failure;
2039+ if (nla_put_u32(skb, DRBD_A_NET_CONF_AFTER_SB_2P, s->after_sb_2p))
2040+ goto nla_put_failure;
2041+ if (nla_put_u32(skb, DRBD_A_NET_CONF_RR_CONFLICT, s->rr_conflict))
2042+ goto nla_put_failure;
2043+ if (nla_put_u32(skb, DRBD_A_NET_CONF_ON_CONGESTION, s->on_congestion))
2044+ goto nla_put_failure;
2045+ if (nla_put_u32(skb, DRBD_A_NET_CONF_CONG_FILL, s->cong_fill))
2046+ goto nla_put_failure;
2047+ if (nla_put_u32(skb, DRBD_A_NET_CONF_CONG_EXTENTS, s->cong_extents))
2048+ goto nla_put_failure;
2049+ if (nla_put_u8(skb, DRBD_A_NET_CONF_TWO_PRIMARIES, s->two_primaries))
2050+ goto nla_put_failure;
2051+ if (nla_put_u8(skb, DRBD_A_NET_CONF_DISCARD_MY_DATA, s->discard_my_data))
2052+ goto nla_put_failure;
2053+ if (nla_put_u8(skb, DRBD_A_NET_CONF_TCP_CORK, s->tcp_cork))
2054+ goto nla_put_failure;
2055+ if (nla_put_u8(skb, DRBD_A_NET_CONF_ALWAYS_ASBP, s->always_asbp))
2056+ goto nla_put_failure;
2057+ if (nla_put_u8(skb, DRBD_A_NET_CONF_TENTATIVE, s->tentative))
2058+ goto nla_put_failure;
2059+ if (nla_put_u8(skb, DRBD_A_NET_CONF_USE_RLE, s->use_rle))
2060+ goto nla_put_failure;
2061+ if (nla_put_u8(skb, DRBD_A_NET_CONF_CSUMS_AFTER_CRASH_ONLY, s->csums_after_crash_only))
2062+ goto nla_put_failure;
2063+ if (nla_put_u32(skb, DRBD_A_NET_CONF_SOCK_CHECK_TIMEO, s->sock_check_timeo))
2064+ goto nla_put_failure;
2065+
2066+ nla_nest_end(skb, tla);
2067+ return 0;
2068+
2069+nla_put_failure:
2070+ if (tla)
2071+ nla_nest_cancel(skb, tla);
2072+ return -EMSGSIZE;
2073+}
2074+
2075+int set_role_parms_to_skb(struct sk_buff *skb, struct set_role_parms *s)
2076+{
2077+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_SET_ROLE_PARMS);
2078+
2079+ if (!tla)
2080+ goto nla_put_failure;
2081+
2082+ if (nla_put_u8(skb, DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE, s->assume_uptodate))
2083+ goto nla_put_failure;
2084+
2085+ nla_nest_end(skb, tla);
2086+ return 0;
2087+
2088+nla_put_failure:
2089+ if (tla)
2090+ nla_nest_cancel(skb, tla);
2091+ return -EMSGSIZE;
2092+}
2093+
2094+int resize_parms_to_skb(struct sk_buff *skb, struct resize_parms *s)
2095+{
2096+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_RESIZE_PARMS);
2097+
2098+ if (!tla)
2099+ goto nla_put_failure;
2100+
2101+ if (nla_put_u64_64bit(skb, DRBD_A_RESIZE_PARMS_RESIZE_SIZE, s->resize_size, 0))
2102+ goto nla_put_failure;
2103+ if (nla_put_u8(skb, DRBD_A_RESIZE_PARMS_RESIZE_FORCE, s->resize_force))
2104+ goto nla_put_failure;
2105+ if (nla_put_u8(skb, DRBD_A_RESIZE_PARMS_NO_RESYNC, s->no_resync))
2106+ goto nla_put_failure;
2107+ if (nla_put_u32(skb, DRBD_A_RESIZE_PARMS_AL_STRIPES, s->al_stripes))
2108+ goto nla_put_failure;
2109+ if (nla_put_u32(skb, DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE, s->al_stripe_size))
2110+ goto nla_put_failure;
2111+
2112+ nla_nest_end(skb, tla);
2113+ return 0;
2114+
2115+nla_put_failure:
2116+ if (tla)
2117+ nla_nest_cancel(skb, tla);
2118+ return -EMSGSIZE;
2119+}
2120+
2121+int state_info_to_skb(struct sk_buff *skb, struct state_info *s)
2122+{
2123+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_STATE_INFO);
2124+
2125+ if (!tla)
2126+ goto nla_put_failure;
2127+
2128+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_SIB_REASON, s->sib_reason))
2129+ goto nla_put_failure;
2130+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_CURRENT_STATE, s->current_state))
2131+ goto nla_put_failure;
2132+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_CAPACITY, s->capacity, 0))
2133+ goto nla_put_failure;
2134+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_ED_UUID, s->ed_uuid, 0))
2135+ goto nla_put_failure;
2136+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_PREV_STATE, s->prev_state))
2137+ goto nla_put_failure;
2138+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_NEW_STATE, s->new_state))
2139+ goto nla_put_failure;
2140+ if (nla_put(skb, DRBD_A_STATE_INFO_UUIDS, min_t(int, DRBD_NL_UUIDS_SIZE,
2141+ s->uuids_len), s->uuids))
2142+ goto nla_put_failure;
2143+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_DISK_FLAGS, s->disk_flags))
2144+ goto nla_put_failure;
2145+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_TOTAL, s->bits_total, 0))
2146+ goto nla_put_failure;
2147+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_OOS, s->bits_oos, 0))
2148+ goto nla_put_failure;
2149+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_RS_TOTAL, s->bits_rs_total, 0))
2150+ goto nla_put_failure;
2151+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_RS_FAILED, s->bits_rs_failed, 0))
2152+ goto nla_put_failure;
2153+ if (nla_put(skb, DRBD_A_STATE_INFO_HELPER, min_t(int, 32,
2154+ s->helper_len + (s->helper_len < 32)), s->helper))
2155+ goto nla_put_failure;
2156+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_HELPER_EXIT_CODE, s->helper_exit_code))
2157+ goto nla_put_failure;
2158+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_SEND_CNT, s->send_cnt, 0))
2159+ goto nla_put_failure;
2160+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_RECV_CNT, s->recv_cnt, 0))
2161+ goto nla_put_failure;
2162+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_READ_CNT, s->read_cnt, 0))
2163+ goto nla_put_failure;
2164+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_WRIT_CNT, s->writ_cnt, 0))
2165+ goto nla_put_failure;
2166+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_AL_WRIT_CNT, s->al_writ_cnt, 0))
2167+ goto nla_put_failure;
2168+ if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BM_WRIT_CNT, s->bm_writ_cnt, 0))
2169+ goto nla_put_failure;
2170+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_AP_BIO_CNT, s->ap_bio_cnt))
2171+ goto nla_put_failure;
2172+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_AP_PENDING_CNT, s->ap_pending_cnt))
2173+ goto nla_put_failure;
2174+ if (nla_put_u32(skb, DRBD_A_STATE_INFO_RS_PENDING_CNT, s->rs_pending_cnt))
2175+ goto nla_put_failure;
2176+
2177+ nla_nest_end(skb, tla);
2178+ return 0;
2179+
2180+nla_put_failure:
2181+ if (tla)
2182+ nla_nest_cancel(skb, tla);
2183+ return -EMSGSIZE;
2184+}
2185+
2186+int start_ov_parms_to_skb(struct sk_buff *skb, struct start_ov_parms *s)
2187+{
2188+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_START_OV_PARMS);
2189+
2190+ if (!tla)
2191+ goto nla_put_failure;
2192+
2193+ if (nla_put_u64_64bit(skb, DRBD_A_START_OV_PARMS_OV_START_SECTOR, s->ov_start_sector, 0))
2194+ goto nla_put_failure;
2195+ if (nla_put_u64_64bit(skb, DRBD_A_START_OV_PARMS_OV_STOP_SECTOR, s->ov_stop_sector, 0))
2196+ goto nla_put_failure;
2197+
2198+ nla_nest_end(skb, tla);
2199+ return 0;
2200+
2201+nla_put_failure:
2202+ if (tla)
2203+ nla_nest_cancel(skb, tla);
2204+ return -EMSGSIZE;
2205+}
2206+
2207+int new_c_uuid_parms_to_skb(struct sk_buff *skb, struct new_c_uuid_parms *s)
2208+{
2209+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_NEW_C_UUID_PARMS);
2210+
2211+ if (!tla)
2212+ goto nla_put_failure;
2213+
2214+ if (nla_put_u8(skb, DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM, s->clear_bm))
2215+ goto nla_put_failure;
2216+
2217+ nla_nest_end(skb, tla);
2218+ return 0;
2219+
2220+nla_put_failure:
2221+ if (tla)
2222+ nla_nest_cancel(skb, tla);
2223+ return -EMSGSIZE;
2224+}
2225+
2226+int timeout_parms_to_skb(struct sk_buff *skb, struct timeout_parms *s)
2227+{
2228+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_TIMEOUT_PARMS);
2229+
2230+ if (!tla)
2231+ goto nla_put_failure;
2232+
2233+ if (nla_put_u32(skb, DRBD_A_TIMEOUT_PARMS_TIMEOUT_TYPE, s->timeout_type))
2234+ goto nla_put_failure;
2235+
2236+ nla_nest_end(skb, tla);
2237+ return 0;
2238+
2239+nla_put_failure:
2240+ if (tla)
2241+ nla_nest_cancel(skb, tla);
2242+ return -EMSGSIZE;
2243+}
2244+
2245+int disconnect_parms_to_skb(struct sk_buff *skb, struct disconnect_parms *s)
2246+{
2247+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_DISCONNECT_PARMS);
2248+
2249+ if (!tla)
2250+ goto nla_put_failure;
2251+
2252+ if (nla_put_u8(skb, DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT, s->force_disconnect))
2253+ goto nla_put_failure;
2254+
2255+ nla_nest_end(skb, tla);
2256+ return 0;
2257+
2258+nla_put_failure:
2259+ if (tla)
2260+ nla_nest_cancel(skb, tla);
2261+ return -EMSGSIZE;
2262+}
2263+
2264+int detach_parms_to_skb(struct sk_buff *skb, struct detach_parms *s)
2265+{
2266+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_DETACH_PARMS);
2267+
2268+ if (!tla)
2269+ goto nla_put_failure;
2270+
2271+ if (nla_put_u8(skb, DRBD_A_DETACH_PARMS_FORCE_DETACH, s->force_detach))
2272+ goto nla_put_failure;
2273+
2274+ nla_nest_end(skb, tla);
2275+ return 0;
2276+
2277+nla_put_failure:
2278+ if (tla)
2279+ nla_nest_cancel(skb, tla);
2280+ return -EMSGSIZE;
2281+}
2282+
2283+int resource_info_to_skb(struct sk_buff *skb, struct resource_info *s)
2284+{
2285+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_RESOURCE_INFO);
2286+
2287+ if (!tla)
2288+ goto nla_put_failure;
2289+
2290+ if (nla_put_u32(skb, DRBD_A_RESOURCE_INFO_RES_ROLE, s->res_role))
2291+ goto nla_put_failure;
2292+ if (nla_put_u8(skb, DRBD_A_RESOURCE_INFO_RES_SUSP, s->res_susp))
2293+ goto nla_put_failure;
2294+ if (nla_put_u8(skb, DRBD_A_RESOURCE_INFO_RES_SUSP_NOD, s->res_susp_nod))
2295+ goto nla_put_failure;
2296+ if (nla_put_u8(skb, DRBD_A_RESOURCE_INFO_RES_SUSP_FEN, s->res_susp_fen))
2297+ goto nla_put_failure;
2298+
2299+ nla_nest_end(skb, tla);
2300+ return 0;
2301+
2302+nla_put_failure:
2303+ if (tla)
2304+ nla_nest_cancel(skb, tla);
2305+ return -EMSGSIZE;
2306+}
2307+
2308+int device_info_to_skb(struct sk_buff *skb, struct device_info *s)
2309+{
2310+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_DEVICE_INFO);
2311+
2312+ if (!tla)
2313+ goto nla_put_failure;
2314+
2315+ if (nla_put_u32(skb, DRBD_A_DEVICE_INFO_DEV_DISK_STATE, s->dev_disk_state))
2316+ goto nla_put_failure;
2317+
2318+ nla_nest_end(skb, tla);
2319+ return 0;
2320+
2321+nla_put_failure:
2322+ if (tla)
2323+ nla_nest_cancel(skb, tla);
2324+ return -EMSGSIZE;
2325+}
2326+
2327+int connection_info_to_skb(struct sk_buff *skb, struct connection_info *s)
2328+{
2329+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_CONNECTION_INFO);
2330+
2331+ if (!tla)
2332+ goto nla_put_failure;
2333+
2334+ if (nla_put_u32(skb, DRBD_A_CONNECTION_INFO_CONN_CONNECTION_STATE, s->conn_connection_state))
2335+ goto nla_put_failure;
2336+ if (nla_put_u32(skb, DRBD_A_CONNECTION_INFO_CONN_ROLE, s->conn_role))
2337+ goto nla_put_failure;
2338+
2339+ nla_nest_end(skb, tla);
2340+ return 0;
2341+
2342+nla_put_failure:
2343+ if (tla)
2344+ nla_nest_cancel(skb, tla);
2345+ return -EMSGSIZE;
2346+}
2347+
2348+int peer_device_info_to_skb(struct sk_buff *skb, struct peer_device_info *s)
2349+{
2350+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_PEER_DEVICE_INFO);
2351+
2352+ if (!tla)
2353+ goto nla_put_failure;
2354+
2355+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_INFO_PEER_REPL_STATE, s->peer_repl_state))
2356+ goto nla_put_failure;
2357+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_INFO_PEER_DISK_STATE, s->peer_disk_state))
2358+ goto nla_put_failure;
2359+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_USER, s->peer_resync_susp_user))
2360+ goto nla_put_failure;
2361+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_PEER, s->peer_resync_susp_peer))
2362+ goto nla_put_failure;
2363+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY, s->peer_resync_susp_dependency))
2364+ goto nla_put_failure;
2365+
2366+ nla_nest_end(skb, tla);
2367+ return 0;
2368+
2369+nla_put_failure:
2370+ if (tla)
2371+ nla_nest_cancel(skb, tla);
2372+ return -EMSGSIZE;
2373+}
2374+
2375+int resource_statistics_to_skb(struct sk_buff *skb, struct resource_statistics *s)
2376+{
2377+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_RESOURCE_STATISTICS);
2378+
2379+ if (!tla)
2380+ goto nla_put_failure;
2381+
2382+ if (nla_put_u32(skb, DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING, s->res_stat_write_ordering))
2383+ goto nla_put_failure;
2384+
2385+ nla_nest_end(skb, tla);
2386+ return 0;
2387+
2388+nla_put_failure:
2389+ if (tla)
2390+ nla_nest_cancel(skb, tla);
2391+ return -EMSGSIZE;
2392+}
2393+
2394+int device_statistics_to_skb(struct sk_buff *skb, struct device_statistics *s)
2395+{
2396+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_DEVICE_STATISTICS);
2397+
2398+ if (!tla)
2399+ goto nla_put_failure;
2400+
2401+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_SIZE, s->dev_size, 0))
2402+ goto nla_put_failure;
2403+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_READ, s->dev_read, 0))
2404+ goto nla_put_failure;
2405+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_WRITE, s->dev_write, 0))
2406+ goto nla_put_failure;
2407+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_AL_WRITES, s->dev_al_writes, 0))
2408+ goto nla_put_failure;
2409+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_BM_WRITES, s->dev_bm_writes, 0))
2410+ goto nla_put_failure;
2411+ if (nla_put_u32(skb, DRBD_A_DEVICE_STATISTICS_DEV_UPPER_PENDING, s->dev_upper_pending))
2412+ goto nla_put_failure;
2413+ if (nla_put_u32(skb, DRBD_A_DEVICE_STATISTICS_DEV_LOWER_PENDING, s->dev_lower_pending))
2414+ goto nla_put_failure;
2415+ if (nla_put_u8(skb, DRBD_A_DEVICE_STATISTICS_DEV_UPPER_BLOCKED, s->dev_upper_blocked))
2416+ goto nla_put_failure;
2417+ if (nla_put_u8(skb, DRBD_A_DEVICE_STATISTICS_DEV_LOWER_BLOCKED, s->dev_lower_blocked))
2418+ goto nla_put_failure;
2419+ if (nla_put_u8(skb, DRBD_A_DEVICE_STATISTICS_DEV_AL_SUSPENDED, s->dev_al_suspended))
2420+ goto nla_put_failure;
2421+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_EXPOSED_DATA_UUID, s->dev_exposed_data_uuid, 0))
2422+ goto nla_put_failure;
2423+ if (nla_put_u64_64bit(skb, DRBD_A_DEVICE_STATISTICS_DEV_CURRENT_UUID, s->dev_current_uuid, 0))
2424+ goto nla_put_failure;
2425+ if (nla_put_u32(skb, DRBD_A_DEVICE_STATISTICS_DEV_DISK_FLAGS, s->dev_disk_flags))
2426+ goto nla_put_failure;
2427+ if (nla_put(skb, DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS, min_t(int, DRBD_NL_HISTORY_UUIDS_SIZE,
2428+ s->history_uuids_len), s->history_uuids))
2429+ goto nla_put_failure;
2430+
2431+ nla_nest_end(skb, tla);
2432+ return 0;
2433+
2434+nla_put_failure:
2435+ if (tla)
2436+ nla_nest_cancel(skb, tla);
2437+ return -EMSGSIZE;
2438+}
2439+
2440+int connection_statistics_to_skb(struct sk_buff *skb, struct connection_statistics *s)
2441+{
2442+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_CONNECTION_STATISTICS);
2443+
2444+ if (!tla)
2445+ goto nla_put_failure;
2446+
2447+ if (nla_put_u8(skb, DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED, s->conn_congested))
2448+ goto nla_put_failure;
2449+
2450+ nla_nest_end(skb, tla);
2451+ return 0;
2452+
2453+nla_put_failure:
2454+ if (tla)
2455+ nla_nest_cancel(skb, tla);
2456+ return -EMSGSIZE;
2457+}
2458+
2459+int peer_device_statistics_to_skb(struct sk_buff *skb, struct peer_device_statistics *s)
2460+{
2461+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_PEER_DEVICE_STATISTICS);
2462+
2463+ if (!tla)
2464+ goto nla_put_failure;
2465+
2466+ if (nla_put_u64_64bit(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RECEIVED, s->peer_dev_received, 0))
2467+ goto nla_put_failure;
2468+ if (nla_put_u64_64bit(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_SENT, s->peer_dev_sent, 0))
2469+ goto nla_put_failure;
2470+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_PENDING, s->peer_dev_pending))
2471+ goto nla_put_failure;
2472+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_UNACKED, s->peer_dev_unacked))
2473+ goto nla_put_failure;
2474+ if (nla_put_u64_64bit(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_OUT_OF_SYNC, s->peer_dev_out_of_sync, 0))
2475+ goto nla_put_failure;
2476+ if (nla_put_u64_64bit(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RESYNC_FAILED, s->peer_dev_resync_failed, 0))
2477+ goto nla_put_failure;
2478+ if (nla_put_u64_64bit(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_BITMAP_UUID, s->peer_dev_bitmap_uuid, 0))
2479+ goto nla_put_failure;
2480+ if (nla_put_u32(skb, DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS, s->peer_dev_flags))
2481+ goto nla_put_failure;
2482+
2483+ nla_nest_end(skb, tla);
2484+ return 0;
2485+
2486+nla_put_failure:
2487+ if (tla)
2488+ nla_nest_cancel(skb, tla);
2489+ return -EMSGSIZE;
2490+}
2491+
2492+int drbd_notification_header_to_skb(struct sk_buff *skb, struct drbd_notification_header *s)
2493+{
2494+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_NOTIFICATION_HEADER);
2495+
2496+ if (!tla)
2497+ goto nla_put_failure;
2498+
2499+ if (nla_put_u32(skb, DRBD_A_DRBD_NOTIFICATION_HEADER_NH_TYPE, s->nh_type))
2500+ goto nla_put_failure;
2501+
2502+ nla_nest_end(skb, tla);
2503+ return 0;
2504+
2505+nla_put_failure:
2506+ if (tla)
2507+ nla_nest_cancel(skb, tla);
2508+ return -EMSGSIZE;
2509+}
2510+
2511+int drbd_helper_info_to_skb(struct sk_buff *skb, struct drbd_helper_info *s)
2512+{
2513+ struct nlattr *tla = nla_nest_start(skb, DRBD_NLA_HELPER);
2514+
2515+ if (!tla)
2516+ goto nla_put_failure;
2517+
2518+ if (nla_put(skb, DRBD_A_DRBD_HELPER_INFO_HELPER_NAME, min_t(int, 32,
2519+ s->helper_name_len + (s->helper_name_len < 32)), s->helper_name))
2520+ goto nla_put_failure;
2521+ if (nla_put_u32(skb, DRBD_A_DRBD_HELPER_INFO_HELPER_STATUS, s->helper_status))
2522+ goto nla_put_failure;
2523+
2524+ nla_nest_end(skb, tla);
2525+ return 0;
2526+
2527+nla_put_failure:
2528+ if (tla)
2529+ nla_nest_cancel(skb, tla);
2530+ return -EMSGSIZE;
2531+}
2532+
2533+void set_disk_conf_defaults(struct disk_conf *x)
2534+{
2535+ x->on_io_error = DRBD_ON_IO_ERROR_DEF;
2536+ x->fencing = DRBD_FENCING_DEF;
2537+ x->resync_rate = DRBD_RESYNC_RATE_DEF;
2538+ x->resync_after = DRBD_MINOR_NUMBER_DEF;
2539+ x->al_extents = DRBD_AL_EXTENTS_DEF;
2540+ x->c_plan_ahead = DRBD_C_PLAN_AHEAD_DEF;
2541+ x->c_delay_target = DRBD_C_DELAY_TARGET_DEF;
2542+ x->c_fill_target = DRBD_C_FILL_TARGET_DEF;
2543+ x->c_max_rate = DRBD_C_MAX_RATE_DEF;
2544+ x->c_min_rate = DRBD_C_MIN_RATE_DEF;
2545+ x->disk_barrier = DRBD_DISK_BARRIER_DEF;
2546+ x->disk_flushes = DRBD_DISK_FLUSHES_DEF;
2547+ x->disk_drain = DRBD_DISK_DRAIN_DEF;
2548+ x->md_flushes = DRBD_MD_FLUSHES_DEF;
2549+ x->disk_timeout = DRBD_DISK_TIMEOUT_DEF;
2550+ x->read_balancing = DRBD_READ_BALANCING_DEF;
2551+ x->al_updates = DRBD_AL_UPDATES_DEF;
2552+ x->discard_zeroes_if_aligned = DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF;
2553+ x->rs_discard_granularity = DRBD_RS_DISCARD_GRANULARITY_DEF;
2554+ x->disable_write_same = DRBD_DISABLE_WRITE_SAME_DEF;
2555+}
2556+
2557+void set_res_opts_defaults(struct res_opts *x)
2558+{
2559+ memset(x->cpu_mask, 0, sizeof(x->cpu_mask));
2560+ x->cpu_mask_len = 0;
2561+ x->on_no_data = DRBD_ON_NO_DATA_DEF;
2562+}
2563+
2564+void set_net_conf_defaults(struct net_conf *x)
2565+{
2566+ memset(x->shared_secret, 0, sizeof(x->shared_secret));
2567+ x->shared_secret_len = 0;
2568+ memset(x->cram_hmac_alg, 0, sizeof(x->cram_hmac_alg));
2569+ x->cram_hmac_alg_len = 0;
2570+ memset(x->integrity_alg, 0, sizeof(x->integrity_alg));
2571+ x->integrity_alg_len = 0;
2572+ memset(x->verify_alg, 0, sizeof(x->verify_alg));
2573+ x->verify_alg_len = 0;
2574+ memset(x->csums_alg, 0, sizeof(x->csums_alg));
2575+ x->csums_alg_len = 0;
2576+ x->wire_protocol = DRBD_PROTOCOL_DEF;
2577+ x->connect_int = DRBD_CONNECT_INT_DEF;
2578+ x->timeout = DRBD_TIMEOUT_DEF;
2579+ x->ping_int = DRBD_PING_INT_DEF;
2580+ x->ping_timeo = DRBD_PING_TIMEO_DEF;
2581+ x->sndbuf_size = DRBD_SNDBUF_SIZE_DEF;
2582+ x->rcvbuf_size = DRBD_RCVBUF_SIZE_DEF;
2583+ x->ko_count = DRBD_KO_COUNT_DEF;
2584+ x->max_buffers = DRBD_MAX_BUFFERS_DEF;
2585+ x->max_epoch_size = DRBD_MAX_EPOCH_SIZE_DEF;
2586+ x->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF;
2587+ x->after_sb_0p = DRBD_AFTER_SB_0P_DEF;
2588+ x->after_sb_1p = DRBD_AFTER_SB_1P_DEF;
2589+ x->after_sb_2p = DRBD_AFTER_SB_2P_DEF;
2590+ x->rr_conflict = DRBD_RR_CONFLICT_DEF;
2591+ x->on_congestion = DRBD_ON_CONGESTION_DEF;
2592+ x->cong_fill = DRBD_CONG_FILL_DEF;
2593+ x->cong_extents = DRBD_CONG_EXTENTS_DEF;
2594+ x->two_primaries = DRBD_ALLOW_TWO_PRIMARIES_DEF;
2595+ x->tcp_cork = DRBD_TCP_CORK_DEF;
2596+ x->always_asbp = DRBD_ALWAYS_ASBP_DEF;
2597+ x->use_rle = DRBD_USE_RLE_DEF;
2598+ x->csums_after_crash_only = DRBD_CSUMS_AFTER_CRASH_ONLY_DEF;
2599+ x->sock_check_timeo = DRBD_SOCKET_CHECK_TIMEO_DEF;
2600+}
2601+
2602+void set_resize_parms_defaults(struct resize_parms *x)
2603+{
2604+ x->al_stripes = DRBD_AL_STRIPES_DEF;
2605+ x->al_stripe_size = DRBD_AL_STRIPE_SIZE_DEF;
2606+}
drivers/block/drbd/drbd_nl_gen.h+395−0
@@ -0,0 +1,395 @@
1+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
2+
3+#ifndef _LINUX_DRBD_GEN_H
4+#define _LINUX_DRBD_GEN_H
5+
6+#include <net/netlink.h>
7+#include <net/genetlink.h>
8+
9+#include <uapi/linux/drbd_genl.h>
10+#include <linux/drbd.h>
11+#include <linux/drbd_limits.h>
12+
13+/* Common nested types */
14+extern const struct nla_policy drbd_connection_info_nl_policy[DRBD_A_CONNECTION_INFO_CONN_ROLE + 1];
15+extern const struct nla_policy drbd_connection_statistics_nl_policy[DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED + 1];
16+extern const struct nla_policy drbd_detach_parms_nl_policy[DRBD_A_DETACH_PARMS_FORCE_DETACH + 1];
17+extern const struct nla_policy drbd_device_info_nl_policy[DRBD_A_DEVICE_INFO_DEV_DISK_STATE + 1];
18+extern const struct nla_policy drbd_device_statistics_nl_policy[DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS + 1];
19+extern const struct nla_policy drbd_disconnect_parms_nl_policy[DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT + 1];
20+extern const struct nla_policy drbd_disk_conf_nl_policy[DRBD_A_DISK_CONF_DISABLE_WRITE_SAME + 1];
21+extern const struct nla_policy drbd_drbd_cfg_context_nl_policy[DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR + 1];
22+extern const struct nla_policy drbd_net_conf_nl_policy[DRBD_A_NET_CONF_SOCK_CHECK_TIMEO + 1];
23+extern const struct nla_policy drbd_new_c_uuid_parms_nl_policy[DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM + 1];
24+extern const struct nla_policy drbd_peer_device_info_nl_policy[DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY + 1];
25+extern const struct nla_policy drbd_peer_device_statistics_nl_policy[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS + 1];
26+extern const struct nla_policy drbd_res_opts_nl_policy[DRBD_A_RES_OPTS_ON_NO_DATA + 1];
27+extern const struct nla_policy drbd_resize_parms_nl_policy[DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE + 1];
28+extern const struct nla_policy drbd_resource_info_nl_policy[DRBD_A_RESOURCE_INFO_RES_SUSP_FEN + 1];
29+extern const struct nla_policy drbd_resource_statistics_nl_policy[DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING + 1];
30+extern const struct nla_policy drbd_set_role_parms_nl_policy[DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE + 1];
31+extern const struct nla_policy drbd_start_ov_parms_nl_policy[DRBD_A_START_OV_PARMS_OV_STOP_SECTOR + 1];
32+
33+/* Ops table for drbd */
34+extern const struct genl_split_ops drbd_nl_ops[32];
35+
36+int drbd_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
37+ struct genl_info *info);
38+void
39+drbd_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
40+ struct genl_info *info);
41+int drbd_adm_dump_devices_done(struct netlink_callback *cb);
42+int drbd_adm_dump_connections_done(struct netlink_callback *cb);
43+int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb);
44+
45+int drbd_nl_get_status_doit(struct sk_buff *skb, struct genl_info *info);
46+int drbd_nl_get_status_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
47+int drbd_nl_new_minor_doit(struct sk_buff *skb, struct genl_info *info);
48+int drbd_nl_del_minor_doit(struct sk_buff *skb, struct genl_info *info);
49+int drbd_nl_new_resource_doit(struct sk_buff *skb, struct genl_info *info);
50+int drbd_nl_del_resource_doit(struct sk_buff *skb, struct genl_info *info);
51+int drbd_nl_resource_opts_doit(struct sk_buff *skb, struct genl_info *info);
52+int drbd_nl_connect_doit(struct sk_buff *skb, struct genl_info *info);
53+int drbd_nl_disconnect_doit(struct sk_buff *skb, struct genl_info *info);
54+int drbd_nl_attach_doit(struct sk_buff *skb, struct genl_info *info);
55+int drbd_nl_resize_doit(struct sk_buff *skb, struct genl_info *info);
56+int drbd_nl_primary_doit(struct sk_buff *skb, struct genl_info *info);
57+int drbd_nl_secondary_doit(struct sk_buff *skb, struct genl_info *info);
58+int drbd_nl_new_c_uuid_doit(struct sk_buff *skb, struct genl_info *info);
59+int drbd_nl_start_ov_doit(struct sk_buff *skb, struct genl_info *info);
60+int drbd_nl_detach_doit(struct sk_buff *skb, struct genl_info *info);
61+int drbd_nl_invalidate_doit(struct sk_buff *skb, struct genl_info *info);
62+int drbd_nl_inval_peer_doit(struct sk_buff *skb, struct genl_info *info);
63+int drbd_nl_pause_sync_doit(struct sk_buff *skb, struct genl_info *info);
64+int drbd_nl_resume_sync_doit(struct sk_buff *skb, struct genl_info *info);
65+int drbd_nl_suspend_io_doit(struct sk_buff *skb, struct genl_info *info);
66+int drbd_nl_resume_io_doit(struct sk_buff *skb, struct genl_info *info);
67+int drbd_nl_outdate_doit(struct sk_buff *skb, struct genl_info *info);
68+int drbd_nl_get_timeout_type_doit(struct sk_buff *skb, struct genl_info *info);
69+int drbd_nl_down_doit(struct sk_buff *skb, struct genl_info *info);
70+int drbd_nl_chg_disk_opts_doit(struct sk_buff *skb, struct genl_info *info);
71+int drbd_nl_chg_net_opts_doit(struct sk_buff *skb, struct genl_info *info);
72+int drbd_nl_get_resources_dumpit(struct sk_buff *skb,
73+ struct netlink_callback *cb);
74+int drbd_nl_get_devices_dumpit(struct sk_buff *skb,
75+ struct netlink_callback *cb);
76+int drbd_nl_get_connections_dumpit(struct sk_buff *skb,
77+ struct netlink_callback *cb);
78+int drbd_nl_get_peer_devices_dumpit(struct sk_buff *skb,
79+ struct netlink_callback *cb);
80+int drbd_nl_get_initial_state_dumpit(struct sk_buff *skb,
81+ struct netlink_callback *cb);
82+
83+enum {
84+ DRBD_NLGRP_EVENTS,
85+};
86+
87+struct drbd_cfg_reply {
88+ char info_text[0];
89+ __u32 info_text_len;
90+};
91+
92+struct drbd_cfg_context {
93+ __u32 ctx_volume;
94+ char ctx_resource_name[128];
95+ __u32 ctx_resource_name_len;
96+ char ctx_my_addr[128];
97+ __u32 ctx_my_addr_len;
98+ char ctx_peer_addr[128];
99+ __u32 ctx_peer_addr_len;
100+};
101+
102+struct disk_conf {
103+ char backing_dev[128];
104+ __u32 backing_dev_len;
105+ char meta_dev[128];
106+ __u32 meta_dev_len;
107+ __s32 meta_dev_idx;
108+ __u64 disk_size;
109+ __u32 max_bio_bvecs;
110+ __u32 on_io_error;
111+ __u32 fencing;
112+ __u32 resync_rate;
113+ __s32 resync_after;
114+ __u32 al_extents;
115+ __u32 c_plan_ahead;
116+ __u32 c_delay_target;
117+ __u32 c_fill_target;
118+ __u32 c_max_rate;
119+ __u32 c_min_rate;
120+ unsigned char disk_barrier;
121+ unsigned char disk_flushes;
122+ unsigned char disk_drain;
123+ unsigned char md_flushes;
124+ __u32 disk_timeout;
125+ __u32 read_balancing;
126+ unsigned char al_updates;
127+ unsigned char discard_zeroes_if_aligned;
128+ __u32 rs_discard_granularity;
129+ unsigned char disable_write_same;
130+};
131+
132+struct res_opts {
133+ char cpu_mask[DRBD_CPU_MASK_SIZE];
134+ __u32 cpu_mask_len;
135+ __u32 on_no_data;
136+};
137+
138+struct net_conf {
139+ char shared_secret[SHARED_SECRET_MAX];
140+ __u32 shared_secret_len;
141+ char cram_hmac_alg[SHARED_SECRET_MAX];
142+ __u32 cram_hmac_alg_len;
143+ char integrity_alg[SHARED_SECRET_MAX];
144+ __u32 integrity_alg_len;
145+ char verify_alg[SHARED_SECRET_MAX];
146+ __u32 verify_alg_len;
147+ char csums_alg[SHARED_SECRET_MAX];
148+ __u32 csums_alg_len;
149+ __u32 wire_protocol;
150+ __u32 connect_int;
151+ __u32 timeout;
152+ __u32 ping_int;
153+ __u32 ping_timeo;
154+ __u32 sndbuf_size;
155+ __u32 rcvbuf_size;
156+ __u32 ko_count;
157+ __u32 max_buffers;
158+ __u32 max_epoch_size;
159+ __u32 unplug_watermark;
160+ __u32 after_sb_0p;
161+ __u32 after_sb_1p;
162+ __u32 after_sb_2p;
163+ __u32 rr_conflict;
164+ __u32 on_congestion;
165+ __u32 cong_fill;
166+ __u32 cong_extents;
167+ unsigned char two_primaries;
168+ unsigned char discard_my_data;
169+ unsigned char tcp_cork;
170+ unsigned char always_asbp;
171+ unsigned char tentative;
172+ unsigned char use_rle;
173+ unsigned char csums_after_crash_only;
174+ __u32 sock_check_timeo;
175+};
176+
177+struct set_role_parms {
178+ unsigned char assume_uptodate;
179+};
180+
181+struct resize_parms {
182+ __u64 resize_size;
183+ unsigned char resize_force;
184+ unsigned char no_resync;
185+ __u32 al_stripes;
186+ __u32 al_stripe_size;
187+};
188+
189+struct state_info {
190+ __u32 sib_reason;
191+ __u32 current_state;
192+ __u64 capacity;
193+ __u64 ed_uuid;
194+ __u32 prev_state;
195+ __u32 new_state;
196+ char uuids[DRBD_NL_UUIDS_SIZE];
197+ __u32 uuids_len;
198+ __u32 disk_flags;
199+ __u64 bits_total;
200+ __u64 bits_oos;
201+ __u64 bits_rs_total;
202+ __u64 bits_rs_failed;
203+ char helper[32];
204+ __u32 helper_len;
205+ __u32 helper_exit_code;
206+ __u64 send_cnt;
207+ __u64 recv_cnt;
208+ __u64 read_cnt;
209+ __u64 writ_cnt;
210+ __u64 al_writ_cnt;
211+ __u64 bm_writ_cnt;
212+ __u32 ap_bio_cnt;
213+ __u32 ap_pending_cnt;
214+ __u32 rs_pending_cnt;
215+};
216+
217+struct start_ov_parms {
218+ __u64 ov_start_sector;
219+ __u64 ov_stop_sector;
220+};
221+
222+struct new_c_uuid_parms {
223+ unsigned char clear_bm;
224+};
225+
226+struct timeout_parms {
227+ __u32 timeout_type;
228+};
229+
230+struct disconnect_parms {
231+ unsigned char force_disconnect;
232+};
233+
234+struct detach_parms {
235+ unsigned char force_detach;
236+};
237+
238+struct resource_info {
239+ __u32 res_role;
240+ unsigned char res_susp;
241+ unsigned char res_susp_nod;
242+ unsigned char res_susp_fen;
243+};
244+
245+struct device_info {
246+ __u32 dev_disk_state;
247+};
248+
249+struct connection_info {
250+ __u32 conn_connection_state;
251+ __u32 conn_role;
252+};
253+
254+struct peer_device_info {
255+ __u32 peer_repl_state;
256+ __u32 peer_disk_state;
257+ __u32 peer_resync_susp_user;
258+ __u32 peer_resync_susp_peer;
259+ __u32 peer_resync_susp_dependency;
260+};
261+
262+struct resource_statistics {
263+ __u32 res_stat_write_ordering;
264+};
265+
266+struct device_statistics {
267+ __u64 dev_size;
268+ __u64 dev_read;
269+ __u64 dev_write;
270+ __u64 dev_al_writes;
271+ __u64 dev_bm_writes;
272+ __u32 dev_upper_pending;
273+ __u32 dev_lower_pending;
274+ unsigned char dev_upper_blocked;
275+ unsigned char dev_lower_blocked;
276+ unsigned char dev_al_suspended;
277+ __u64 dev_exposed_data_uuid;
278+ __u64 dev_current_uuid;
279+ __u32 dev_disk_flags;
280+ char history_uuids[DRBD_NL_HISTORY_UUIDS_SIZE];
281+ __u32 history_uuids_len;
282+};
283+
284+struct connection_statistics {
285+ unsigned char conn_congested;
286+};
287+
288+struct peer_device_statistics {
289+ __u64 peer_dev_received;
290+ __u64 peer_dev_sent;
291+ __u32 peer_dev_pending;
292+ __u32 peer_dev_unacked;
293+ __u64 peer_dev_out_of_sync;
294+ __u64 peer_dev_resync_failed;
295+ __u64 peer_dev_bitmap_uuid;
296+ __u32 peer_dev_flags;
297+};
298+
299+struct drbd_notification_header {
300+ __u32 nh_type;
301+};
302+
303+struct drbd_helper_info {
304+ char helper_name[32];
305+ __u32 helper_name_len;
306+ __u32 helper_status;
307+};
308+
309+int drbd_cfg_reply_to_skb(struct sk_buff *skb, struct drbd_cfg_reply *s);
310+
311+int drbd_cfg_context_from_attrs(struct drbd_cfg_context *s, struct genl_info *info);
312+int drbd_cfg_context_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
313+int drbd_cfg_context_to_skb(struct sk_buff *skb, struct drbd_cfg_context *s);
314+
315+int disk_conf_from_attrs(struct disk_conf *s, struct genl_info *info);
316+int disk_conf_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
317+int disk_conf_to_skb(struct sk_buff *skb, struct disk_conf *s);
318+void set_disk_conf_defaults(struct disk_conf *x);
319+
320+int res_opts_from_attrs(struct res_opts *s, struct genl_info *info);
321+int res_opts_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
322+int res_opts_to_skb(struct sk_buff *skb, struct res_opts *s);
323+void set_res_opts_defaults(struct res_opts *x);
324+
325+int net_conf_from_attrs(struct net_conf *s, struct genl_info *info);
326+int net_conf_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
327+int net_conf_to_skb(struct sk_buff *skb, struct net_conf *s);
328+void set_net_conf_defaults(struct net_conf *x);
329+
330+int set_role_parms_from_attrs(struct set_role_parms *s, struct genl_info *info);
331+int set_role_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
332+int set_role_parms_to_skb(struct sk_buff *skb, struct set_role_parms *s);
333+
334+int resize_parms_from_attrs(struct resize_parms *s, struct genl_info *info);
335+int resize_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
336+int resize_parms_to_skb(struct sk_buff *skb, struct resize_parms *s);
337+void set_resize_parms_defaults(struct resize_parms *x);
338+
339+int state_info_to_skb(struct sk_buff *skb, struct state_info *s);
340+
341+int start_ov_parms_from_attrs(struct start_ov_parms *s, struct genl_info *info);
342+int start_ov_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
343+int start_ov_parms_to_skb(struct sk_buff *skb, struct start_ov_parms *s);
344+
345+int new_c_uuid_parms_from_attrs(struct new_c_uuid_parms *s, struct genl_info *info);
346+int new_c_uuid_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
347+int new_c_uuid_parms_to_skb(struct sk_buff *skb, struct new_c_uuid_parms *s);
348+
349+int timeout_parms_to_skb(struct sk_buff *skb, struct timeout_parms *s);
350+
351+int disconnect_parms_from_attrs(struct disconnect_parms *s, struct genl_info *info);
352+int disconnect_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
353+int disconnect_parms_to_skb(struct sk_buff *skb, struct disconnect_parms *s);
354+
355+int detach_parms_from_attrs(struct detach_parms *s, struct genl_info *info);
356+int detach_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
357+int detach_parms_to_skb(struct sk_buff *skb, struct detach_parms *s);
358+
359+int resource_info_from_attrs(struct resource_info *s, struct genl_info *info);
360+int resource_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
361+int resource_info_to_skb(struct sk_buff *skb, struct resource_info *s);
362+
363+int device_info_from_attrs(struct device_info *s, struct genl_info *info);
364+int device_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
365+int device_info_to_skb(struct sk_buff *skb, struct device_info *s);
366+
367+int connection_info_from_attrs(struct connection_info *s, struct genl_info *info);
368+int connection_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
369+int connection_info_to_skb(struct sk_buff *skb, struct connection_info *s);
370+
371+int peer_device_info_from_attrs(struct peer_device_info *s, struct genl_info *info);
372+int peer_device_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
373+int peer_device_info_to_skb(struct sk_buff *skb, struct peer_device_info *s);
374+
375+int resource_statistics_from_attrs(struct resource_statistics *s, struct genl_info *info);
376+int resource_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
377+int resource_statistics_to_skb(struct sk_buff *skb, struct resource_statistics *s);
378+
379+int device_statistics_from_attrs(struct device_statistics *s, struct genl_info *info);
380+int device_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
381+int device_statistics_to_skb(struct sk_buff *skb, struct device_statistics *s);
382+
383+int connection_statistics_from_attrs(struct connection_statistics *s, struct genl_info *info);
384+int connection_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
385+int connection_statistics_to_skb(struct sk_buff *skb, struct connection_statistics *s);
386+
387+int peer_device_statistics_from_attrs(struct peer_device_statistics *s, struct genl_info *info);
388+int peer_device_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
389+int peer_device_statistics_to_skb(struct sk_buff *skb, struct peer_device_statistics *s);
390+
391+int drbd_notification_header_to_skb(struct sk_buff *skb, struct drbd_notification_header *s);
392+
393+int drbd_helper_info_to_skb(struct sk_buff *skb, struct drbd_helper_info *s);
394+
395+#endif /* _LINUX_DRBD_GEN_H */
drivers/block/drbd/drbd_proc.c+1−1
@@ -228,7 +228,7 @@ int drbd_seq_show(struct seq_file *seq, void *v) · 227 unmodified lines
228228 };
229229
230230 seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
231− GENL_MAGIC_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
231+ DRBD_FAMILY_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
232232
233233 /*
234234 cs .. connection state
include/linux/drbd_genl.h+0−536
@@ -1,536 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−/*
3− * General overview:
4− * full generic netlink message:
5− * |nlmsghdr|genlmsghdr|<payload>
6− *
7− * payload:
8− * |optional fixed size family header|<sequence of netlink attributes>
9− *
10− * sequence of netlink attributes:
11− * I chose to have all "top level" attributes NLA_NESTED,
12− * corresponding to some real struct.
13− * So we have a sequence of |tla, len|<nested nla sequence>
14− *
15− * nested nla sequence:
16− * may be empty, or contain a sequence of netlink attributes
17− * representing the struct fields.
18− *
19− * The tag number of any field (regardless of containing struct)
20− * will be available as T_ ## field_name,
21− * so you cannot have the same field name in two differnt structs.
22− *
23− * The tag numbers themselves are per struct, though,
24− * so should always begin at 1 (not 0, that is the special "NLA_UNSPEC" type,
25− * which we won't use here).
26− * The tag numbers are used as index in the respective nla_policy array.
27− *
28− * GENL_struct(tag_name, tag_number, struct name, struct fields) - struct and policy
29− * genl_magic_struct.h
30− * generates the struct declaration,
31− * generates an entry in the tla enum,
32− * genl_magic_func.h
33− * generates an entry in the static tla policy
34− * with .type = NLA_NESTED
35− * generates the static <struct_name>_nl_policy definition,
36− * and static conversion functions
37− *
38− * genl_magic_func.h
39− *
40− * GENL_mc_group(group)
41− * genl_magic_struct.h
42− * does nothing
43− * genl_magic_func.h
44− * defines and registers the mcast group,
45− * and provides a send helper
46− *
47− * GENL_notification(op_name, op_num, mcast_group, tla list)
48− * These are notifications to userspace.
49− *
50− * genl_magic_struct.h
51− * generates an entry in the genl_ops enum,
52− * genl_magic_func.h
53− * does nothing
54− *
55− * mcast group: the name of the mcast group this notification should be
56− * expected on
57− * tla list: the list of expected top level attributes,
58− * for documentation and sanity checking.
59− *
60− * GENL_op(op_name, op_num, flags and handler, tla list) - "genl operations"
61− * These are requests from userspace.
62− *
63− * _op and _notification share the same "number space",
64− * op_nr will be assigned to "genlmsghdr->cmd"
65− *
66− * genl_magic_struct.h
67− * generates an entry in the genl_ops enum,
68− * genl_magic_func.h
69− * generates an entry in the static genl_ops array,
70− * and static register/unregister functions to
71− * genl_register_family().
72− *
73− * flags and handler:
74− * GENL_op_init( .doit = x, .dumpit = y, .flags = something)
75− * GENL_doit(x) => .dumpit = NULL, .flags = GENL_ADMIN_PERM
76− * tla list: the list of expected top level attributes,
77− * for documentation and sanity checking.
78− */
79−
80−/*
81− * STRUCTS
82− */
83−
84−/* this is sent kernel -> userland on various error conditions, and contains
85− * informational textual info, which is supposedly human readable.
86− * The computer relevant return code is in the drbd_genlmsghdr.
87− */
88−GENL_struct(DRBD_NLA_CFG_REPLY, 1, drbd_cfg_reply,
89− /* "arbitrary" size strings, nla_policy.len = 0 */
90− __str_field(1, 0, info_text, 0)
91−)
92−
93−/* Configuration requests typically need a context to operate on.
94− * Possible keys are device minor (fits in the drbd_genlmsghdr),
95− * the replication link (aka connection) name,
96− * and/or the replication group (aka resource) name,
97− * and the volume id within the resource. */
98−GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context,
99− __u32_field(1, 0, ctx_volume)
100− __str_field(2, 0, ctx_resource_name, 128)
101− __bin_field(3, 0, ctx_my_addr, 128)
102− __bin_field(4, 0, ctx_peer_addr, 128)
103−)
104−
105−GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
106− __str_field(1, DRBD_F_REQUIRED | DRBD_F_INVARIANT, backing_dev, 128)
107− __str_field(2, DRBD_F_REQUIRED | DRBD_F_INVARIANT, meta_dev, 128)
108− __s32_field(3, DRBD_F_REQUIRED | DRBD_F_INVARIANT, meta_dev_idx)
109−
110− /* use the resize command to try and change the disk_size */
111− __u64_field(4, DRBD_F_INVARIANT, disk_size)
112− /* we could change the max_bio_bvecs,
113− * but it won't propagate through the stack */
114− __u32_field(5, DRBD_F_INVARIANT, max_bio_bvecs)
115−
116− __u32_field_def(6, 0, on_io_error, DRBD_ON_IO_ERROR_DEF)
117− __u32_field_def(7, 0, fencing, DRBD_FENCING_DEF)
118−
119− __u32_field_def(8, 0, resync_rate, DRBD_RESYNC_RATE_DEF)
120− __s32_field_def(9, 0, resync_after, DRBD_MINOR_NUMBER_DEF)
121− __u32_field_def(10, 0, al_extents, DRBD_AL_EXTENTS_DEF)
122− __u32_field_def(11, 0, c_plan_ahead, DRBD_C_PLAN_AHEAD_DEF)
123− __u32_field_def(12, 0, c_delay_target, DRBD_C_DELAY_TARGET_DEF)
124− __u32_field_def(13, 0, c_fill_target, DRBD_C_FILL_TARGET_DEF)
125− __u32_field_def(14, 0, c_max_rate, DRBD_C_MAX_RATE_DEF)
126− __u32_field_def(15, 0, c_min_rate, DRBD_C_MIN_RATE_DEF)
127− __u32_field_def(20, 0, disk_timeout, DRBD_DISK_TIMEOUT_DEF)
128− __u32_field_def(21, 0 /* OPTIONAL */, read_balancing, DRBD_READ_BALANCING_DEF)
129− __u32_field_def(25, 0 /* OPTIONAL */, rs_discard_granularity, DRBD_RS_DISCARD_GRANULARITY_DEF)
130−
131− __flg_field_def(16, 0, disk_barrier, DRBD_DISK_BARRIER_DEF)
132− __flg_field_def(17, 0, disk_flushes, DRBD_DISK_FLUSHES_DEF)
133− __flg_field_def(18, 0, disk_drain, DRBD_DISK_DRAIN_DEF)
134− __flg_field_def(19, 0, md_flushes, DRBD_MD_FLUSHES_DEF)
135− __flg_field_def(23, 0 /* OPTIONAL */, al_updates, DRBD_AL_UPDATES_DEF)
136− __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF)
137− __flg_field_def(26, 0 /* OPTIONAL */, disable_write_same, DRBD_DISABLE_WRITE_SAME_DEF)
138−)
139−
140−GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts,
141− __str_field_def(1, 0, cpu_mask, DRBD_CPU_MASK_SIZE)
142− __u32_field_def(2, 0, on_no_data, DRBD_ON_NO_DATA_DEF)
143−)
144−
145−GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf,
146− __str_field_def(1, DRBD_F_SENSITIVE,
147− shared_secret, SHARED_SECRET_MAX)
148− __str_field_def(2, 0, cram_hmac_alg, SHARED_SECRET_MAX)
149− __str_field_def(3, 0, integrity_alg, SHARED_SECRET_MAX)
150− __str_field_def(4, 0, verify_alg, SHARED_SECRET_MAX)
151− __str_field_def(5, 0, csums_alg, SHARED_SECRET_MAX)
152− __u32_field_def(6, 0, wire_protocol, DRBD_PROTOCOL_DEF)
153− __u32_field_def(7, 0, connect_int, DRBD_CONNECT_INT_DEF)
154− __u32_field_def(8, 0, timeout, DRBD_TIMEOUT_DEF)
155− __u32_field_def(9, 0, ping_int, DRBD_PING_INT_DEF)
156− __u32_field_def(10, 0, ping_timeo, DRBD_PING_TIMEO_DEF)
157− __u32_field_def(11, 0, sndbuf_size, DRBD_SNDBUF_SIZE_DEF)
158− __u32_field_def(12, 0, rcvbuf_size, DRBD_RCVBUF_SIZE_DEF)
159− __u32_field_def(13, 0, ko_count, DRBD_KO_COUNT_DEF)
160− __u32_field_def(14, 0, max_buffers, DRBD_MAX_BUFFERS_DEF)
161− __u32_field_def(15, 0, max_epoch_size, DRBD_MAX_EPOCH_SIZE_DEF)
162− __u32_field_def(16, 0, unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF)
163− __u32_field_def(17, 0, after_sb_0p, DRBD_AFTER_SB_0P_DEF)
164− __u32_field_def(18, 0, after_sb_1p, DRBD_AFTER_SB_1P_DEF)
165− __u32_field_def(19, 0, after_sb_2p, DRBD_AFTER_SB_2P_DEF)
166− __u32_field_def(20, 0, rr_conflict, DRBD_RR_CONFLICT_DEF)
167− __u32_field_def(21, 0, on_congestion, DRBD_ON_CONGESTION_DEF)
168− __u32_field_def(22, 0, cong_fill, DRBD_CONG_FILL_DEF)
169− __u32_field_def(23, 0, cong_extents, DRBD_CONG_EXTENTS_DEF)
170− __flg_field_def(24, 0, two_primaries, DRBD_ALLOW_TWO_PRIMARIES_DEF)
171− __flg_field(25, DRBD_F_INVARIANT, discard_my_data)
172− __flg_field_def(26, 0, tcp_cork, DRBD_TCP_CORK_DEF)
173− __flg_field_def(27, 0, always_asbp, DRBD_ALWAYS_ASBP_DEF)
174− __flg_field(28, DRBD_F_INVARIANT, tentative)
175− __flg_field_def(29, 0, use_rle, DRBD_USE_RLE_DEF)
176− /* 9: __u32_field_def(30, 0, fencing_policy, DRBD_FENCING_DEF) */
177− /* 9: __str_field_def(31, 0, name, SHARED_SECRET_MAX) */
178− /* 9: __u32_field(32, DRBD_F_REQUIRED | DRBD_F_INVARIANT, peer_node_id) */
179− __flg_field_def(33, 0 /* OPTIONAL */, csums_after_crash_only, DRBD_CSUMS_AFTER_CRASH_ONLY_DEF)
180− __u32_field_def(34, 0 /* OPTIONAL */, sock_check_timeo, DRBD_SOCKET_CHECK_TIMEO_DEF)
181−)
182−
183−GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms,
184− __flg_field(1, 0, assume_uptodate)
185−)
186−
187−GENL_struct(DRBD_NLA_RESIZE_PARMS, 7, resize_parms,
188− __u64_field(1, 0, resize_size)
189− __flg_field(2, 0, resize_force)
190− __flg_field(3, 0, no_resync)
191− __u32_field_def(4, 0 /* OPTIONAL */, al_stripes, DRBD_AL_STRIPES_DEF)
192− __u32_field_def(5, 0 /* OPTIONAL */, al_stripe_size, DRBD_AL_STRIPE_SIZE_DEF)
193−)
194−
195−GENL_struct(DRBD_NLA_STATE_INFO, 8, state_info,
196− /* the reason of the broadcast,
197− * if this is an event triggered broadcast. */
198− __u32_field(1, 0, sib_reason)
199− __u32_field(2, DRBD_F_REQUIRED, current_state)
200− __u64_field(3, 0, capacity)
201− __u64_field(4, 0, ed_uuid)
202−
203− /* These are for broadcast from after state change work.
204− * prev_state and new_state are from the moment the state change took
205− * place, new_state is not neccessarily the same as current_state,
206− * there may have been more state changes since. Which will be
207− * broadcasted soon, in their respective after state change work. */
208− __u32_field(5, 0, prev_state)
209− __u32_field(6, 0, new_state)
210−
211− /* if we have a local disk: */
212− __bin_field(7, 0, uuids, (UI_SIZE*sizeof(__u64)))
213− __u32_field(8, 0, disk_flags)
214− __u64_field(9, 0, bits_total)
215− __u64_field(10, 0, bits_oos)
216− /* and in case resync or online verify is active */
217− __u64_field(11, 0, bits_rs_total)
218− __u64_field(12, 0, bits_rs_failed)
219−
220− /* for pre and post notifications of helper execution */
221− __str_field(13, 0, helper, 32)
222− __u32_field(14, 0, helper_exit_code)
223−
224− __u64_field(15, 0, send_cnt)
225− __u64_field(16, 0, recv_cnt)
226− __u64_field(17, 0, read_cnt)
227− __u64_field(18, 0, writ_cnt)
228− __u64_field(19, 0, al_writ_cnt)
229− __u64_field(20, 0, bm_writ_cnt)
230− __u32_field(21, 0, ap_bio_cnt)
231− __u32_field(22, 0, ap_pending_cnt)
232− __u32_field(23, 0, rs_pending_cnt)
233−)
234−
235−GENL_struct(DRBD_NLA_START_OV_PARMS, 9, start_ov_parms,
236− __u64_field(1, 0, ov_start_sector)
237− __u64_field(2, 0, ov_stop_sector)
238−)
239−
240−GENL_struct(DRBD_NLA_NEW_C_UUID_PARMS, 10, new_c_uuid_parms,
241− __flg_field(1, 0, clear_bm)
242−)
243−
244−GENL_struct(DRBD_NLA_TIMEOUT_PARMS, 11, timeout_parms,
245− __u32_field(1, DRBD_F_REQUIRED, timeout_type)
246−)
247−
248−GENL_struct(DRBD_NLA_DISCONNECT_PARMS, 12, disconnect_parms,
249− __flg_field(1, 0, force_disconnect)
250−)
251−
252−GENL_struct(DRBD_NLA_DETACH_PARMS, 13, detach_parms,
253− __flg_field(1, 0, force_detach)
254−)
255−
256−GENL_struct(DRBD_NLA_RESOURCE_INFO, 15, resource_info,
257− __u32_field(1, 0, res_role)
258− __flg_field(2, 0, res_susp)
259− __flg_field(3, 0, res_susp_nod)
260− __flg_field(4, 0, res_susp_fen)
261− /* __flg_field(5, 0, res_weak) */
262−)
263−
264−GENL_struct(DRBD_NLA_DEVICE_INFO, 16, device_info,
265− __u32_field(1, 0, dev_disk_state)
266−)
267−
268−GENL_struct(DRBD_NLA_CONNECTION_INFO, 17, connection_info,
269− __u32_field(1, 0, conn_connection_state)
270− __u32_field(2, 0, conn_role)
271−)
272−
273−GENL_struct(DRBD_NLA_PEER_DEVICE_INFO, 18, peer_device_info,
274− __u32_field(1, 0, peer_repl_state)
275− __u32_field(2, 0, peer_disk_state)
276− __u32_field(3, 0, peer_resync_susp_user)
277− __u32_field(4, 0, peer_resync_susp_peer)
278− __u32_field(5, 0, peer_resync_susp_dependency)
279−)
280−
281−GENL_struct(DRBD_NLA_RESOURCE_STATISTICS, 19, resource_statistics,
282− __u32_field(1, 0, res_stat_write_ordering)
283−)
284−
285−GENL_struct(DRBD_NLA_DEVICE_STATISTICS, 20, device_statistics,
286− __u64_field(1, 0, dev_size) /* (sectors) */
287− __u64_field(2, 0, dev_read) /* (sectors) */
288− __u64_field(3, 0, dev_write) /* (sectors) */
289− __u64_field(4, 0, dev_al_writes) /* activity log writes (count) */
290− __u64_field(5, 0, dev_bm_writes) /* bitmap writes (count) */
291− __u32_field(6, 0, dev_upper_pending) /* application requests in progress */
292− __u32_field(7, 0, dev_lower_pending) /* backing device requests in progress */
293− __flg_field(8, 0, dev_upper_blocked)
294− __flg_field(9, 0, dev_lower_blocked)
295− __flg_field(10, 0, dev_al_suspended) /* activity log suspended */
296− __u64_field(11, 0, dev_exposed_data_uuid)
297− __u64_field(12, 0, dev_current_uuid)
298− __u32_field(13, 0, dev_disk_flags)
299− __bin_field(14, 0, history_uuids, HISTORY_UUIDS * sizeof(__u64))
300−)
301−
302−GENL_struct(DRBD_NLA_CONNECTION_STATISTICS, 21, connection_statistics,
303− __flg_field(1, 0, conn_congested)
304−)
305−
306−GENL_struct(DRBD_NLA_PEER_DEVICE_STATISTICS, 22, peer_device_statistics,
307− __u64_field(1, 0, peer_dev_received) /* sectors */
308− __u64_field(2, 0, peer_dev_sent) /* sectors */
309− __u32_field(3, 0, peer_dev_pending) /* number of requests */
310− __u32_field(4, 0, peer_dev_unacked) /* number of requests */
311− __u64_field(5, 0, peer_dev_out_of_sync) /* sectors */
312− __u64_field(6, 0, peer_dev_resync_failed) /* sectors */
313− __u64_field(7, 0, peer_dev_bitmap_uuid)
314− __u32_field(9, 0, peer_dev_flags)
315−)
316−
317−GENL_struct(DRBD_NLA_NOTIFICATION_HEADER, 23, drbd_notification_header,
318− __u32_field(1, 0, nh_type)
319−)
320−
321−GENL_struct(DRBD_NLA_HELPER, 24, drbd_helper_info,
322− __str_field(1, 0, helper_name, 32)
323− __u32_field(2, 0, helper_status)
324−)
325−
326−/*
327− * Notifications and commands (genlmsghdr->cmd)
328− */
329−GENL_mc_group(events)
330−
331− /* kernel -> userspace announcement of changes */
332−GENL_notification(
333− DRBD_EVENT, 1, events,
334− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
335− GENL_tla_expected(DRBD_NLA_STATE_INFO, DRBD_F_REQUIRED)
336− GENL_tla_expected(DRBD_NLA_NET_CONF, 0)
337− GENL_tla_expected(DRBD_NLA_DISK_CONF, 0)
338− GENL_tla_expected(DRBD_NLA_SYNCER_CONF, 0)
339−)
340−
341− /* query kernel for specific or all info */
342−GENL_op(
343− DRBD_ADM_GET_STATUS, 2,
344− GENL_op_init(
345− .doit = drbd_adm_get_status,
346− .dumpit = drbd_adm_get_status_all,
347− /* anyone may ask for the status,
348− * it is broadcasted anyways */
349− ),
350− /* To select the object .doit.
351− * Or a subset of objects in .dumpit. */
352− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, 0)
353−)
354−
355− /* add DRBD minor devices as volumes to resources */
356−GENL_op(DRBD_ADM_NEW_MINOR, 5, GENL_doit(drbd_adm_new_minor),
357− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
358−GENL_op(DRBD_ADM_DEL_MINOR, 6, GENL_doit(drbd_adm_del_minor),
359− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
360−
361− /* add or delete resources */
362−GENL_op(DRBD_ADM_NEW_RESOURCE, 7, GENL_doit(drbd_adm_new_resource),
363− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
364−GENL_op(DRBD_ADM_DEL_RESOURCE, 8, GENL_doit(drbd_adm_del_resource),
365− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
366−
367−GENL_op(DRBD_ADM_RESOURCE_OPTS, 9,
368− GENL_doit(drbd_adm_resource_opts),
369− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
370− GENL_tla_expected(DRBD_NLA_RESOURCE_OPTS, 0)
371−)
372−
373−GENL_op(
374− DRBD_ADM_CONNECT, 10,
375− GENL_doit(drbd_adm_connect),
376− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
377− GENL_tla_expected(DRBD_NLA_NET_CONF, DRBD_F_REQUIRED)
378−)
379−
380−GENL_op(
381− DRBD_ADM_CHG_NET_OPTS, 29,
382− GENL_doit(drbd_adm_net_opts),
383− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
384− GENL_tla_expected(DRBD_NLA_NET_CONF, DRBD_F_REQUIRED)
385−)
386−
387−GENL_op(DRBD_ADM_DISCONNECT, 11, GENL_doit(drbd_adm_disconnect),
388− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
389−
390−GENL_op(DRBD_ADM_ATTACH, 12,
391− GENL_doit(drbd_adm_attach),
392− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
393− GENL_tla_expected(DRBD_NLA_DISK_CONF, DRBD_F_REQUIRED)
394−)
395−
396−GENL_op(DRBD_ADM_CHG_DISK_OPTS, 28,
397− GENL_doit(drbd_adm_disk_opts),
398− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
399− GENL_tla_expected(DRBD_NLA_DISK_OPTS, DRBD_F_REQUIRED)
400−)
401−
402−GENL_op(
403− DRBD_ADM_RESIZE, 13,
404− GENL_doit(drbd_adm_resize),
405− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
406− GENL_tla_expected(DRBD_NLA_RESIZE_PARMS, 0)
407−)
408−
409−GENL_op(
410− DRBD_ADM_PRIMARY, 14,
411− GENL_doit(drbd_adm_set_role),
412− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
413− GENL_tla_expected(DRBD_NLA_SET_ROLE_PARMS, DRBD_F_REQUIRED)
414−)
415−
416−GENL_op(
417− DRBD_ADM_SECONDARY, 15,
418− GENL_doit(drbd_adm_set_role),
419− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
420− GENL_tla_expected(DRBD_NLA_SET_ROLE_PARMS, DRBD_F_REQUIRED)
421−)
422−
423−GENL_op(
424− DRBD_ADM_NEW_C_UUID, 16,
425− GENL_doit(drbd_adm_new_c_uuid),
426− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
427− GENL_tla_expected(DRBD_NLA_NEW_C_UUID_PARMS, 0)
428−)
429−
430−GENL_op(
431− DRBD_ADM_START_OV, 17,
432− GENL_doit(drbd_adm_start_ov),
433− GENL_tla_expected(DRBD_NLA_START_OV_PARMS, 0)
434−)
435−
436−GENL_op(DRBD_ADM_DETACH, 18, GENL_doit(drbd_adm_detach),
437− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
438− GENL_tla_expected(DRBD_NLA_DETACH_PARMS, 0))
439−
440−GENL_op(DRBD_ADM_INVALIDATE, 19, GENL_doit(drbd_adm_invalidate),
441− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
442−GENL_op(DRBD_ADM_INVAL_PEER, 20, GENL_doit(drbd_adm_invalidate_peer),
443− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
444−GENL_op(DRBD_ADM_PAUSE_SYNC, 21, GENL_doit(drbd_adm_pause_sync),
445− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
446−GENL_op(DRBD_ADM_RESUME_SYNC, 22, GENL_doit(drbd_adm_resume_sync),
447− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
448−GENL_op(DRBD_ADM_SUSPEND_IO, 23, GENL_doit(drbd_adm_suspend_io),
449− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
450−GENL_op(DRBD_ADM_RESUME_IO, 24, GENL_doit(drbd_adm_resume_io),
451− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
452−GENL_op(DRBD_ADM_OUTDATE, 25, GENL_doit(drbd_adm_outdate),
453− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
454−GENL_op(DRBD_ADM_GET_TIMEOUT_TYPE, 26, GENL_doit(drbd_adm_get_timeout_type),
455− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
456−GENL_op(DRBD_ADM_DOWN, 27, GENL_doit(drbd_adm_down),
457− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED))
458−
459−GENL_op(DRBD_ADM_GET_RESOURCES, 30,
460− GENL_op_init(
461− .dumpit = drbd_adm_dump_resources,
462− ),
463− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, 0)
464− GENL_tla_expected(DRBD_NLA_RESOURCE_INFO, 0)
465− GENL_tla_expected(DRBD_NLA_RESOURCE_STATISTICS, 0))
466−
467−GENL_op(DRBD_ADM_GET_DEVICES, 31,
468− GENL_op_init(
469− .dumpit = drbd_adm_dump_devices,
470− .done = drbd_adm_dump_devices_done,
471− ),
472− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, 0)
473− GENL_tla_expected(DRBD_NLA_DEVICE_INFO, 0)
474− GENL_tla_expected(DRBD_NLA_DEVICE_STATISTICS, 0))
475−
476−GENL_op(DRBD_ADM_GET_CONNECTIONS, 32,
477− GENL_op_init(
478− .dumpit = drbd_adm_dump_connections,
479− .done = drbd_adm_dump_connections_done,
480− ),
481− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, 0)
482− GENL_tla_expected(DRBD_NLA_CONNECTION_INFO, 0)
483− GENL_tla_expected(DRBD_NLA_CONNECTION_STATISTICS, 0))
484−
485−GENL_op(DRBD_ADM_GET_PEER_DEVICES, 33,
486− GENL_op_init(
487− .dumpit = drbd_adm_dump_peer_devices,
488− .done = drbd_adm_dump_peer_devices_done,
489− ),
490− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, 0)
491− GENL_tla_expected(DRBD_NLA_PEER_DEVICE_INFO, 0)
492− GENL_tla_expected(DRBD_NLA_PEER_DEVICE_STATISTICS, 0))
493−
494−GENL_notification(
495− DRBD_RESOURCE_STATE, 34, events,
496− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
497− GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
498− GENL_tla_expected(DRBD_NLA_RESOURCE_INFO, DRBD_F_REQUIRED)
499− GENL_tla_expected(DRBD_NLA_RESOURCE_STATISTICS, DRBD_F_REQUIRED))
500−
501−GENL_notification(
502− DRBD_DEVICE_STATE, 35, events,
503− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
504− GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
505− GENL_tla_expected(DRBD_NLA_DEVICE_INFO, DRBD_F_REQUIRED)
506− GENL_tla_expected(DRBD_NLA_DEVICE_STATISTICS, DRBD_F_REQUIRED))
507−
508−GENL_notification(
509− DRBD_CONNECTION_STATE, 36, events,
510− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
511− GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
512− GENL_tla_expected(DRBD_NLA_CONNECTION_INFO, DRBD_F_REQUIRED)
513− GENL_tla_expected(DRBD_NLA_CONNECTION_STATISTICS, DRBD_F_REQUIRED))
514−
515−GENL_notification(
516− DRBD_PEER_DEVICE_STATE, 37, events,
517− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
518− GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)
519− GENL_tla_expected(DRBD_NLA_PEER_DEVICE_INFO, DRBD_F_REQUIRED)
520− GENL_tla_expected(DRBD_NLA_PEER_DEVICE_STATISTICS, DRBD_F_REQUIRED))
521−
522−GENL_op(
523− DRBD_ADM_GET_INITIAL_STATE, 38,
524− GENL_op_init(
525− .dumpit = drbd_adm_get_initial_state,
526− ),
527− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, 0))
528−
529−GENL_notification(
530− DRBD_HELPER, 40, events,
531− GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)
532− GENL_tla_expected(DRBD_NLA_HELPER, DRBD_F_REQUIRED))
533−
534−GENL_notification(
535− DRBD_INITIAL_STATE_DONE, 41, events,
536− GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED))
include/linux/drbd_genl_api.h+0−16
@@ -1,16 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−#ifndef DRBD_GENL_STRUCT_H
3−#define DRBD_GENL_STRUCT_H
4−
5−/* hack around predefined gcc/cpp "linux=1",
6− * we cannot possibly include <1/drbd_genl.h> */
7−#undef linux
8−
9−#include <linux/drbd.h>
10−#define GENL_MAGIC_VERSION 1
11−#define GENL_MAGIC_FAMILY drbd
12−#define GENL_MAGIC_FAMILY_HDRSZ sizeof(struct drbd_genlmsghdr)
13−#define GENL_MAGIC_INCLUDE_FILE <linux/drbd_genl.h>
14−#include <linux/genl_magic_struct.h>
15−
16−#endif
include/linux/genl_magic_func.h+0−413
@@ -1,413 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−#ifndef GENL_MAGIC_FUNC_H
3−#define GENL_MAGIC_FUNC_H
4−
5−#include <linux/args.h>
6−#include <linux/build_bug.h>
7−#include <linux/genl_magic_struct.h>
8−
9−/*
10− * Magic: declare tla policy {{{1
11− * Magic: declare nested policies
12− * {{{2
13− */
14−#undef GENL_mc_group
15−#define GENL_mc_group(group)
16−
17−#undef GENL_notification
18−#define GENL_notification(op_name, op_num, mcast_group, tla_list)
19−
20−#undef GENL_op
21−#define GENL_op(op_name, op_num, handler, tla_list)
22−
23−#undef GENL_struct
24−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
25− [tag_name] = { .type = NLA_NESTED },
26−
27−static struct nla_policy CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = {
28−#include GENL_MAGIC_INCLUDE_FILE
29−};
30−
31−#undef GENL_struct
32−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
33−static struct nla_policy s_name ## _nl_policy[] __read_mostly = \
34−{ s_fields };
35−
36−#undef __field
37−#define __field(attr_nr, attr_flag, name, nla_type, _type, __get, \
38− __put, __is_signed) \
39− [attr_nr] = { .type = nla_type },
40−
41−#undef __array
42−#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen, \
43− __get, __put, __is_signed) \
44− [attr_nr] = { .type = nla_type, \
45− .len = maxlen - (nla_type == NLA_NUL_STRING) },
46−
47−#include GENL_MAGIC_INCLUDE_FILE
48−
49−#ifndef __KERNEL__
50−#ifndef pr_info
51−#define pr_info(args...) fprintf(stderr, args);
52−#endif
53−#endif
54−
55−#ifdef GENL_MAGIC_DEBUG
56−static void dprint_field(const char *dir, int nla_type,
57− const char *name, void *valp)
58−{
59− __u64 val = valp ? *(__u32 *)valp : 1;
60− switch (nla_type) {
61− case NLA_U8: val = (__u8)val;
62− case NLA_U16: val = (__u16)val;
63− case NLA_U32: val = (__u32)val;
64− pr_info("%s attr %s: %d 0x%08x\n", dir,
65− name, (int)val, (unsigned)val);
66− break;
67− case NLA_U64:
68− val = *(__u64*)valp;
69− pr_info("%s attr %s: %lld 0x%08llx\n", dir,
70− name, (long long)val, (unsigned long long)val);
71− break;
72− case NLA_FLAG:
73− if (val)
74− pr_info("%s attr %s: set\n", dir, name);
75− break;
76− }
77−}
78−
79−static void dprint_array(const char *dir, int nla_type,
80− const char *name, const char *val, unsigned len)
81−{
82− switch (nla_type) {
83− case NLA_NUL_STRING:
84− if (len && val[len-1] == '\0')
85− len--;
86− pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
87− break;
88− default:
89− /* we can always show 4 byte,
90− * thats what nlattr are aligned to. */
91− pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
92− dir, name, len, val[0], val[1], val[2], val[3]);
93− }
94−}
95−
96−#define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b);
97−
98−/* Name is a member field name of the struct s.
99− * If s is NULL (only parsing, no copy requested in *_from_attrs()),
100− * nla is supposed to point to the attribute containing the information
101− * corresponding to that struct member. */
102−#define DPRINT_FIELD(dir, nla_type, name, s, nla) \
103− do { \
104− if (s) \
105− dprint_field(dir, nla_type, #name, &s->name); \
106− else if (nla) \
107− dprint_field(dir, nla_type, #name, \
108− (nla_type == NLA_FLAG) ? NULL \
109− : nla_data(nla)); \
110− } while (0)
111−
112−#define DPRINT_ARRAY(dir, nla_type, name, s, nla) \
113− do { \
114− if (s) \
115− dprint_array(dir, nla_type, #name, \
116− s->name, s->name ## _len); \
117− else if (nla) \
118− dprint_array(dir, nla_type, #name, \
119− nla_data(nla), nla_len(nla)); \
120− } while (0)
121−#else
122−#define DPRINT_TLA(a, op, b) do {} while (0)
123−#define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0)
124−#define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0)
125−#endif
126−
127−/*
128− * Magic: provide conversion functions {{{1
129− * populate struct from attribute table:
130− * {{{2
131− */
132−
133−/* processing of generic netlink messages is serialized.
134− * use one static buffer for parsing of nested attributes */
135−static struct nlattr *nested_attr_tb[128];
136−
137−#undef GENL_struct
138−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
139−/* *_from_attrs functions are static, but potentially unused */ \
140−static int __ ## s_name ## _from_attrs(struct s_name *s, \
141− struct genl_info *info, bool exclude_invariants) \
142−{ \
143− const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \
144− struct nlattr *tla = info->attrs[tag_number]; \
145− struct nlattr **ntb = nested_attr_tb; \
146− struct nlattr *nla; \
147− int err; \
148− BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb)); \
149− if (!tla) \
150− return -ENOMSG; \
151− DPRINT_TLA(#s_name, "<=-", #tag_name); \
152− err = nla_parse_nested_deprecated(ntb, maxtype, tla, \
153− s_name ## _nl_policy, NULL); \
154− if (err) \
155− return err; \
156− \
157− s_fields \
158− return 0; \
159−} __attribute__((unused)) \
160−static int s_name ## _from_attrs(struct s_name *s, \
161− struct genl_info *info) \
162−{ \
163− return __ ## s_name ## _from_attrs(s, info, false); \
164−} __attribute__((unused)) \
165−static int s_name ## _from_attrs_for_change(struct s_name *s, \
166− struct genl_info *info) \
167−{ \
168− return __ ## s_name ## _from_attrs(s, info, true); \
169−} __attribute__((unused)) \
170−
171−#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...) \
172− nla = ntb[attr_nr]; \
173− if (nla) { \
174− if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) { \
175− pr_info("<< must not change invariant attr: %s\n", #name); \
176− return -EEXIST; \
177− } \
178− assignment; \
179− } else if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) { \
180− /* attribute missing from payload, */ \
181− /* which was expected */ \
182− } else if ((attr_flag) & DRBD_F_REQUIRED) { \
183− pr_info("<< missing attr: %s\n", #name); \
184− return -ENOMSG; \
185− }
186−
187−#undef __field
188−#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
189− __is_signed) \
190− __assign(attr_nr, attr_flag, name, nla_type, type, \
191− if (s) \
192− s->name = __get(nla); \
193− DPRINT_FIELD("<<", nla_type, name, s, nla))
194−
195−/* validate_nla() already checked nla_len <= maxlen appropriately. */
196−#undef __array
197−#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
198− __get, __put, __is_signed) \
199− __assign(attr_nr, attr_flag, name, nla_type, type, \
200− if (s) \
201− s->name ## _len = \
202− __get(s->name, nla, maxlen); \
203− DPRINT_ARRAY("<<", nla_type, name, s, nla))
204−
205−#include GENL_MAGIC_INCLUDE_FILE
206−
207−#undef GENL_struct
208−#define GENL_struct(tag_name, tag_number, s_name, s_fields)
209−
210−/*
211− * Magic: define op number to op name mapping {{{1
212− * {{{2
213− */
214−static const char *CONCATENATE(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
215−{
216− switch (cmd) {
217−#undef GENL_op
218−#define GENL_op(op_name, op_num, handler, tla_list) \
219− case op_num: return #op_name;
220−#include GENL_MAGIC_INCLUDE_FILE
221− default:
222− return "unknown";
223− }
224−}
225−
226−#ifdef __KERNEL__
227−#include <linux/stringify.h>
228−/*
229− * Magic: define genl_ops {{{1
230− * {{{2
231− */
232−
233−#undef GENL_op
234−#define GENL_op(op_name, op_num, handler, tla_list) \
235−{ \
236− handler \
237− .cmd = op_name, \
238−},
239−
240−#define ZZZ_genl_ops CONCATENATE(GENL_MAGIC_FAMILY, _genl_ops)
241−static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
242−#include GENL_MAGIC_INCLUDE_FILE
243−};
244−
245−#undef GENL_op
246−#define GENL_op(op_name, op_num, handler, tla_list)
247−
248−/*
249− * Define the genl_family, multicast groups, {{{1
250− * and provide register/unregister functions.
251− * {{{2
252− */
253−#define ZZZ_genl_family CONCATENATE(GENL_MAGIC_FAMILY, _genl_family)
254−static struct genl_family ZZZ_genl_family;
255−/*
256− * Magic: define multicast groups
257− * Magic: define multicast group registration helper
258− */
259−#define ZZZ_genl_mcgrps CONCATENATE(GENL_MAGIC_FAMILY, _genl_mcgrps)
260−static const struct genl_multicast_group ZZZ_genl_mcgrps[] = {
261−#undef GENL_mc_group
262−#define GENL_mc_group(group) { .name = #group, },
263−#include GENL_MAGIC_INCLUDE_FILE
264−};
265−
266−enum CONCATENATE(GENL_MAGIC_FAMILY, group_ids) {
267−#undef GENL_mc_group
268−#define GENL_mc_group(group) CONCATENATE(GENL_MAGIC_FAMILY, _group_ ## group),
269−#include GENL_MAGIC_INCLUDE_FILE
270−};
271−
272−#undef GENL_mc_group
273−#define GENL_mc_group(group) \
274−static int CONCATENATE(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \
275− struct sk_buff *skb, gfp_t flags) \
276−{ \
277− unsigned int group_id = \
278− CONCATENATE(GENL_MAGIC_FAMILY, _group_ ## group); \
279− return genlmsg_multicast(&ZZZ_genl_family, skb, 0, \
280− group_id, flags); \
281−}
282−
283−#include GENL_MAGIC_INCLUDE_FILE
284−
285−#undef GENL_mc_group
286−#define GENL_mc_group(group)
287−
288−static struct genl_family ZZZ_genl_family __ro_after_init = {
289− .name = __stringify(GENL_MAGIC_FAMILY),
290− .version = GENL_MAGIC_VERSION,
291−#ifdef GENL_MAGIC_FAMILY_HDRSZ
292− .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
293−#endif
294− .maxattr = ARRAY_SIZE(CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy))-1,
295− .policy = CONCATENATE(GENL_MAGIC_FAMILY, _tla_nl_policy),
296−#ifdef GENL_MAGIC_FAMILY_PRE_DOIT
297− .pre_doit = GENL_MAGIC_FAMILY_PRE_DOIT,
298− .post_doit = GENL_MAGIC_FAMILY_POST_DOIT,
299−#endif
300− .ops = ZZZ_genl_ops,
301− .n_ops = ARRAY_SIZE(ZZZ_genl_ops),
302− .mcgrps = ZZZ_genl_mcgrps,
303− .resv_start_op = 42, /* drbd is currently the only user */
304− .n_mcgrps = ARRAY_SIZE(ZZZ_genl_mcgrps),
305− .module = THIS_MODULE,
306−};
307−
308−int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void)
309−{
310− return genl_register_family(&ZZZ_genl_family);
311−}
312−
313−void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void)
314−{
315− genl_unregister_family(&ZZZ_genl_family);
316−}
317−
318−/*
319− * Magic: provide conversion functions {{{1
320− * populate skb from struct.
321− * {{{2
322− */
323−
324−#undef GENL_op
325−#define GENL_op(op_name, op_num, handler, tla_list)
326−
327−#undef GENL_struct
328−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
329−static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \
330− const bool exclude_sensitive) \
331−{ \
332− struct nlattr *tla = nla_nest_start(skb, tag_number); \
333− if (!tla) \
334− goto nla_put_failure; \
335− DPRINT_TLA(#s_name, "-=>", #tag_name); \
336− s_fields \
337− nla_nest_end(skb, tla); \
338− return 0; \
339− \
340−nla_put_failure: \
341− if (tla) \
342− nla_nest_cancel(skb, tla); \
343− return -EMSGSIZE; \
344−} \
345−static inline int s_name ## _to_priv_skb(struct sk_buff *skb, \
346− struct s_name *s) \
347−{ \
348− return s_name ## _to_skb(skb, s, 0); \
349−} \
350−static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \
351− struct s_name *s) \
352−{ \
353− return s_name ## _to_skb(skb, s, 1); \
354−}
355−
356−
357−#undef __field
358−#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
359− __is_signed) \
360− if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) { \
361− DPRINT_FIELD(">>", nla_type, name, s, NULL); \
362− if (__put(skb, attr_nr, s->name)) \
363− goto nla_put_failure; \
364− }
365−
366−#undef __array
367−#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
368− __get, __put, __is_signed) \
369− if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) { \
370− DPRINT_ARRAY(">>",nla_type, name, s, NULL); \
371− if (__put(skb, attr_nr, min_t(int, maxlen, \
372− s->name ## _len + (nla_type == NLA_NUL_STRING)),\
373− s->name)) \
374− goto nla_put_failure; \
375− }
376−
377−#include GENL_MAGIC_INCLUDE_FILE
378−
379−
380−/* Functions for initializing structs to default values. */
381−
382−#undef __field
383−#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
384− __is_signed)
385−#undef __array
386−#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
387− __get, __put, __is_signed)
388−#undef __u32_field_def
389−#define __u32_field_def(attr_nr, attr_flag, name, default) \
390− x->name = default;
391−#undef __s32_field_def
392−#define __s32_field_def(attr_nr, attr_flag, name, default) \
393− x->name = default;
394−#undef __flg_field_def
395−#define __flg_field_def(attr_nr, attr_flag, name, default) \
396− x->name = default;
397−#undef __str_field_def
398−#define __str_field_def(attr_nr, attr_flag, name, maxlen) \
399− memset(x->name, 0, sizeof(x->name)); \
400− x->name ## _len = 0;
401−#undef GENL_struct
402−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
403−static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
404−static void set_ ## s_name ## _defaults(struct s_name *x) { \
405−s_fields \
406−}
407−
408−#include GENL_MAGIC_INCLUDE_FILE
409−
410−#endif /* __KERNEL__ */
411−
412−/* }}}1 */
413−#endif /* GENL_MAGIC_FUNC_H */
include/linux/genl_magic_struct.h+0−272
@@ -1,272 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−#ifndef GENL_MAGIC_STRUCT_H
3−#define GENL_MAGIC_STRUCT_H
4−
5−#ifndef GENL_MAGIC_FAMILY
6−# error "you need to define GENL_MAGIC_FAMILY before inclusion"
7−#endif
8−
9−#ifndef GENL_MAGIC_VERSION
10−# error "you need to define GENL_MAGIC_VERSION before inclusion"
11−#endif
12−
13−#ifndef GENL_MAGIC_INCLUDE_FILE
14−# error "you need to define GENL_MAGIC_INCLUDE_FILE before inclusion"
15−#endif
16−
17−#include <linux/args.h>
18−#include <linux/types.h>
19−#include <net/genetlink.h>
20−
21−extern int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void);
22−extern void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void);
23−
24−/*
25− * Extension of genl attribute validation policies {{{2
26− */
27−
28−/*
29− * Flags specific to drbd and not visible at the netlink layer, used in
30− * <struct>_from_attrs and <struct>_to_skb:
31− *
32− * @DRBD_F_REQUIRED: Attribute is required; a request without this attribute is
33− * invalid.
34− *
35− * @DRBD_F_SENSITIVE: Attribute includes sensitive information and must not be
36− * included in unpriviledged get requests or broadcasts.
37− *
38− * @DRBD_F_INVARIANT: Attribute is set when an object is initially created, but
39− * cannot subsequently be changed.
40− */
41−#define DRBD_F_REQUIRED (1 << 0)
42−#define DRBD_F_SENSITIVE (1 << 1)
43−#define DRBD_F_INVARIANT (1 << 2)
44−
45−
46−/* }}}1
47− * MAGIC
48− * multi-include macro expansion magic starts here
49− */
50−
51−/* MAGIC helpers {{{2 */
52−
53−static inline int nla_put_u64_0pad(struct sk_buff *skb, int attrtype, u64 value)
54−{
55− return nla_put_64bit(skb, attrtype, sizeof(u64), &value, 0);
56−}
57−
58−/* possible field types */
59−#define __flg_field(attr_nr, attr_flag, name) \
60− __field(attr_nr, attr_flag, name, NLA_U8, char, \
61− nla_get_u8, nla_put_u8, false)
62−#define __u8_field(attr_nr, attr_flag, name) \
63− __field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \
64− nla_get_u8, nla_put_u8, false)
65−#define __u16_field(attr_nr, attr_flag, name) \
66− __field(attr_nr, attr_flag, name, NLA_U16, __u16, \
67− nla_get_u16, nla_put_u16, false)
68−#define __u32_field(attr_nr, attr_flag, name) \
69− __field(attr_nr, attr_flag, name, NLA_U32, __u32, \
70− nla_get_u32, nla_put_u32, false)
71−#define __s32_field(attr_nr, attr_flag, name) \
72− __field(attr_nr, attr_flag, name, NLA_U32, __s32, \
73− nla_get_u32, nla_put_u32, true)
74−#define __u64_field(attr_nr, attr_flag, name) \
75− __field(attr_nr, attr_flag, name, NLA_U64, __u64, \
76− nla_get_u64, nla_put_u64_0pad, false)
77−#define __str_field(attr_nr, attr_flag, name, maxlen) \
78− __array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
79− nla_strscpy, nla_put, false)
80−#define __bin_field(attr_nr, attr_flag, name, maxlen) \
81− __array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \
82− nla_memcpy, nla_put, false)
83−
84−/* fields with default values */
85−#define __flg_field_def(attr_nr, attr_flag, name, default) \
86− __flg_field(attr_nr, attr_flag, name)
87−#define __u32_field_def(attr_nr, attr_flag, name, default) \
88− __u32_field(attr_nr, attr_flag, name)
89−#define __s32_field_def(attr_nr, attr_flag, name, default) \
90− __s32_field(attr_nr, attr_flag, name)
91−#define __str_field_def(attr_nr, attr_flag, name, maxlen) \
92− __str_field(attr_nr, attr_flag, name, maxlen)
93−
94−#define GENL_op_init(args...) args
95−#define GENL_doit(handler) \
96− .doit = handler, \
97− .flags = GENL_ADMIN_PERM,
98−#define GENL_dumpit(handler) \
99− .dumpit = handler, \
100− .flags = GENL_ADMIN_PERM,
101−
102−/* }}}1
103− * Magic: define the enum symbols for genl_ops
104− * Magic: define the enum symbols for top level attributes
105− * Magic: define the enum symbols for nested attributes
106− * {{{2
107− */
108−
109−#undef GENL_struct
110−#define GENL_struct(tag_name, tag_number, s_name, s_fields)
111−
112−#undef GENL_mc_group
113−#define GENL_mc_group(group)
114−
115−#undef GENL_notification
116−#define GENL_notification(op_name, op_num, mcast_group, tla_list) \
117− op_name = op_num,
118−
119−#undef GENL_op
120−#define GENL_op(op_name, op_num, handler, tla_list) \
121− op_name = op_num,
122−
123−enum {
124−#include GENL_MAGIC_INCLUDE_FILE
125−};
126−
127−#undef GENL_notification
128−#define GENL_notification(op_name, op_num, mcast_group, tla_list)
129−
130−#undef GENL_op
131−#define GENL_op(op_name, op_num, handler, attr_list)
132−
133−#undef GENL_struct
134−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
135− tag_name = tag_number,
136−
137−enum {
138−#include GENL_MAGIC_INCLUDE_FILE
139−};
140−
141−#undef GENL_struct
142−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
143−enum { \
144− s_fields \
145−};
146−
147−#undef __field
148−#define __field(attr_nr, attr_flag, name, nla_type, type, \
149− __get, __put, __is_signed) \
150− T_ ## name = (__u16)(attr_nr),
151−
152−#undef __array
153−#define __array(attr_nr, attr_flag, name, nla_type, type, \
154− maxlen, __get, __put, __is_signed) \
155− T_ ## name = (__u16)(attr_nr),
156−
157−#include GENL_MAGIC_INCLUDE_FILE
158−
159−/* }}}1
160− * Magic: compile time assert unique numbers for operations
161− * Magic: -"- unique numbers for top level attributes
162− * Magic: -"- unique numbers for nested attributes
163− * {{{2
164− */
165−
166−#undef GENL_struct
167−#define GENL_struct(tag_name, tag_number, s_name, s_fields)
168−
169−#undef GENL_op
170−#define GENL_op(op_name, op_num, handler, attr_list) \
171− case op_name:
172−
173−#undef GENL_notification
174−#define GENL_notification(op_name, op_num, mcast_group, tla_list) \
175− case op_name:
176−
177−static inline void ct_assert_unique_operations(void)
178−{
179− switch (0) {
180−#include GENL_MAGIC_INCLUDE_FILE
181− case 0:
182− ;
183− }
184−}
185−
186−#undef GENL_op
187−#define GENL_op(op_name, op_num, handler, attr_list)
188−
189−#undef GENL_notification
190−#define GENL_notification(op_name, op_num, mcast_group, tla_list)
191−
192−#undef GENL_struct
193−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
194− case tag_number:
195−
196−static inline void ct_assert_unique_top_level_attributes(void)
197−{
198− switch (0) {
199−#include GENL_MAGIC_INCLUDE_FILE
200− case 0:
201− ;
202− }
203−}
204−
205−#undef GENL_struct
206−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
207−static inline void ct_assert_unique_ ## s_name ## _attributes(void) \
208−{ \
209− switch (0) { \
210− s_fields \
211− case 0: \
212− ; \
213− } \
214−}
215−
216−#undef __field
217−#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
218− __is_signed) \
219− case attr_nr:
220−
221−#undef __array
222−#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
223− __get, __put, __is_signed) \
224− case attr_nr:
225−
226−#include GENL_MAGIC_INCLUDE_FILE
227−
228−/* }}}1
229− * Magic: declare structs
230− * struct <name> {
231− * fields
232− * };
233− * {{{2
234− */
235−
236−#undef GENL_struct
237−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
238−struct s_name { s_fields };
239−
240−#undef __field
241−#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
242− __is_signed) \
243− type name;
244−
245−#undef __array
246−#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
247− __get, __put, __is_signed) \
248− type name[maxlen]; \
249− __u32 name ## _len;
250−
251−#include GENL_MAGIC_INCLUDE_FILE
252−
253−#undef GENL_struct
254−#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
255−enum { \
256− s_fields \
257−};
258−
259−#undef __field
260−#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
261− is_signed) \
262− F_ ## name ## _IS_SIGNED = is_signed,
263−
264−#undef __array
265−#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \
266− __get, __put, is_signed) \
267− F_ ## name ## _IS_SIGNED = is_signed,
268−
269−#include GENL_MAGIC_INCLUDE_FILE
270−
271−/* }}}1 */
272−#endif /* GENL_MAGIC_STRUCT_H */
include/uapi/linux/drbd.h+3−0
@@ -333,6 +333,9 @@ enum drbd_uuid_index { · 332 unmodified lines
333333
334334 #define HISTORY_UUIDS MAX_PEERS
335335
336+#define DRBD_NL_UUIDS_SIZE (UI_SIZE * sizeof(__u64))
337+#define DRBD_NL_HISTORY_UUIDS_SIZE (HISTORY_UUIDS * sizeof(__u64))
338+
336339 enum drbd_timeout_flag {
337340 UT_DEFAULT = 0,
338341 UT_DEGRADED = 1,
include/uapi/linux/drbd_genl.h+359−0
@@ -0,0 +1,359 @@
1+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
2+
3+#ifndef _UAPI_LINUX_DRBD_GENL_H
4+#define _UAPI_LINUX_DRBD_GENL_H
5+
6+#define DRBD_FAMILY_NAME "drbd"
7+#define DRBD_FAMILY_VERSION 1
8+
9+enum {
10+ DRBD_NLA_CFG_REPLY = 1,
11+ DRBD_NLA_CFG_CONTEXT,
12+ DRBD_NLA_DISK_CONF,
13+ DRBD_NLA_RESOURCE_OPTS,
14+ DRBD_NLA_NET_CONF,
15+ DRBD_NLA_SET_ROLE_PARMS,
16+ DRBD_NLA_RESIZE_PARMS,
17+ DRBD_NLA_STATE_INFO,
18+ DRBD_NLA_START_OV_PARMS,
19+ DRBD_NLA_NEW_C_UUID_PARMS,
20+ DRBD_NLA_TIMEOUT_PARMS,
21+ DRBD_NLA_DISCONNECT_PARMS,
22+ DRBD_NLA_DETACH_PARMS,
23+ DRBD_NLA_RESOURCE_INFO = 15,
24+ DRBD_NLA_DEVICE_INFO,
25+ DRBD_NLA_CONNECTION_INFO,
26+ DRBD_NLA_PEER_DEVICE_INFO,
27+ DRBD_NLA_RESOURCE_STATISTICS,
28+ DRBD_NLA_DEVICE_STATISTICS,
29+ DRBD_NLA_CONNECTION_STATISTICS,
30+ DRBD_NLA_PEER_DEVICE_STATISTICS,
31+ DRBD_NLA_NOTIFICATION_HEADER,
32+ DRBD_NLA_HELPER,
33+
34+ __DRBD_NLA_MAX,
35+ DRBD_NLA_MAX = (__DRBD_NLA_MAX - 1)
36+};
37+
38+enum {
39+ DRBD_A_DRBD_CFG_REPLY_INFO_TEXT = 1,
40+
41+ __DRBD_A_DRBD_CFG_REPLY_MAX,
42+ DRBD_A_DRBD_CFG_REPLY_MAX = (__DRBD_A_DRBD_CFG_REPLY_MAX - 1)
43+};
44+
45+enum {
46+ DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME = 1,
47+ DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME,
48+ DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR,
49+ DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR,
50+
51+ __DRBD_A_DRBD_CFG_CONTEXT_MAX,
52+ DRBD_A_DRBD_CFG_CONTEXT_MAX = (__DRBD_A_DRBD_CFG_CONTEXT_MAX - 1)
53+};
54+
55+enum {
56+ DRBD_A_DISK_CONF_BACKING_DEV = 1,
57+ DRBD_A_DISK_CONF_META_DEV,
58+ DRBD_A_DISK_CONF_META_DEV_IDX,
59+ DRBD_A_DISK_CONF_DISK_SIZE,
60+ DRBD_A_DISK_CONF_MAX_BIO_BVECS,
61+ DRBD_A_DISK_CONF_ON_IO_ERROR,
62+ DRBD_A_DISK_CONF_FENCING,
63+ DRBD_A_DISK_CONF_RESYNC_RATE,
64+ DRBD_A_DISK_CONF_RESYNC_AFTER,
65+ DRBD_A_DISK_CONF_AL_EXTENTS,
66+ DRBD_A_DISK_CONF_C_PLAN_AHEAD,
67+ DRBD_A_DISK_CONF_C_DELAY_TARGET,
68+ DRBD_A_DISK_CONF_C_FILL_TARGET,
69+ DRBD_A_DISK_CONF_C_MAX_RATE,
70+ DRBD_A_DISK_CONF_C_MIN_RATE,
71+ DRBD_A_DISK_CONF_DISK_BARRIER,
72+ DRBD_A_DISK_CONF_DISK_FLUSHES,
73+ DRBD_A_DISK_CONF_DISK_DRAIN,
74+ DRBD_A_DISK_CONF_MD_FLUSHES,
75+ DRBD_A_DISK_CONF_DISK_TIMEOUT,
76+ DRBD_A_DISK_CONF_READ_BALANCING,
77+ DRBD_A_DISK_CONF_AL_UPDATES = 23,
78+ DRBD_A_DISK_CONF_DISCARD_ZEROES_IF_ALIGNED,
79+ DRBD_A_DISK_CONF_RS_DISCARD_GRANULARITY,
80+ DRBD_A_DISK_CONF_DISABLE_WRITE_SAME,
81+
82+ __DRBD_A_DISK_CONF_MAX,
83+ DRBD_A_DISK_CONF_MAX = (__DRBD_A_DISK_CONF_MAX - 1)
84+};
85+
86+enum {
87+ DRBD_A_RES_OPTS_CPU_MASK = 1,
88+ DRBD_A_RES_OPTS_ON_NO_DATA,
89+
90+ __DRBD_A_RES_OPTS_MAX,
91+ DRBD_A_RES_OPTS_MAX = (__DRBD_A_RES_OPTS_MAX - 1)
92+};
93+
94+enum {
95+ DRBD_A_NET_CONF_SHARED_SECRET = 1,
96+ DRBD_A_NET_CONF_CRAM_HMAC_ALG,
97+ DRBD_A_NET_CONF_INTEGRITY_ALG,
98+ DRBD_A_NET_CONF_VERIFY_ALG,
99+ DRBD_A_NET_CONF_CSUMS_ALG,
100+ DRBD_A_NET_CONF_WIRE_PROTOCOL,
101+ DRBD_A_NET_CONF_CONNECT_INT,
102+ DRBD_A_NET_CONF_TIMEOUT,
103+ DRBD_A_NET_CONF_PING_INT,
104+ DRBD_A_NET_CONF_PING_TIMEO,
105+ DRBD_A_NET_CONF_SNDBUF_SIZE,
106+ DRBD_A_NET_CONF_RCVBUF_SIZE,
107+ DRBD_A_NET_CONF_KO_COUNT,
108+ DRBD_A_NET_CONF_MAX_BUFFERS,
109+ DRBD_A_NET_CONF_MAX_EPOCH_SIZE,
110+ DRBD_A_NET_CONF_UNPLUG_WATERMARK,
111+ DRBD_A_NET_CONF_AFTER_SB_0P,
112+ DRBD_A_NET_CONF_AFTER_SB_1P,
113+ DRBD_A_NET_CONF_AFTER_SB_2P,
114+ DRBD_A_NET_CONF_RR_CONFLICT,
115+ DRBD_A_NET_CONF_ON_CONGESTION,
116+ DRBD_A_NET_CONF_CONG_FILL,
117+ DRBD_A_NET_CONF_CONG_EXTENTS,
118+ DRBD_A_NET_CONF_TWO_PRIMARIES,
119+ DRBD_A_NET_CONF_DISCARD_MY_DATA,
120+ DRBD_A_NET_CONF_TCP_CORK,
121+ DRBD_A_NET_CONF_ALWAYS_ASBP,
122+ DRBD_A_NET_CONF_TENTATIVE,
123+ DRBD_A_NET_CONF_USE_RLE,
124+ DRBD_A_NET_CONF_CSUMS_AFTER_CRASH_ONLY = 33,
125+ DRBD_A_NET_CONF_SOCK_CHECK_TIMEO,
126+
127+ __DRBD_A_NET_CONF_MAX,
128+ DRBD_A_NET_CONF_MAX = (__DRBD_A_NET_CONF_MAX - 1)
129+};
130+
131+enum {
132+ DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE = 1,
133+
134+ __DRBD_A_SET_ROLE_PARMS_MAX,
135+ DRBD_A_SET_ROLE_PARMS_MAX = (__DRBD_A_SET_ROLE_PARMS_MAX - 1)
136+};
137+
138+enum {
139+ DRBD_A_RESIZE_PARMS_RESIZE_SIZE = 1,
140+ DRBD_A_RESIZE_PARMS_RESIZE_FORCE,
141+ DRBD_A_RESIZE_PARMS_NO_RESYNC,
142+ DRBD_A_RESIZE_PARMS_AL_STRIPES,
143+ DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE,
144+
145+ __DRBD_A_RESIZE_PARMS_MAX,
146+ DRBD_A_RESIZE_PARMS_MAX = (__DRBD_A_RESIZE_PARMS_MAX - 1)
147+};
148+
149+enum {
150+ DRBD_A_STATE_INFO_SIB_REASON = 1,
151+ DRBD_A_STATE_INFO_CURRENT_STATE,
152+ DRBD_A_STATE_INFO_CAPACITY,
153+ DRBD_A_STATE_INFO_ED_UUID,
154+ DRBD_A_STATE_INFO_PREV_STATE,
155+ DRBD_A_STATE_INFO_NEW_STATE,
156+ DRBD_A_STATE_INFO_UUIDS,
157+ DRBD_A_STATE_INFO_DISK_FLAGS,
158+ DRBD_A_STATE_INFO_BITS_TOTAL,
159+ DRBD_A_STATE_INFO_BITS_OOS,
160+ DRBD_A_STATE_INFO_BITS_RS_TOTAL,
161+ DRBD_A_STATE_INFO_BITS_RS_FAILED,
162+ DRBD_A_STATE_INFO_HELPER,
163+ DRBD_A_STATE_INFO_HELPER_EXIT_CODE,
164+ DRBD_A_STATE_INFO_SEND_CNT,
165+ DRBD_A_STATE_INFO_RECV_CNT,
166+ DRBD_A_STATE_INFO_READ_CNT,
167+ DRBD_A_STATE_INFO_WRIT_CNT,
168+ DRBD_A_STATE_INFO_AL_WRIT_CNT,
169+ DRBD_A_STATE_INFO_BM_WRIT_CNT,
170+ DRBD_A_STATE_INFO_AP_BIO_CNT,
171+ DRBD_A_STATE_INFO_AP_PENDING_CNT,
172+ DRBD_A_STATE_INFO_RS_PENDING_CNT,
173+
174+ __DRBD_A_STATE_INFO_MAX,
175+ DRBD_A_STATE_INFO_MAX = (__DRBD_A_STATE_INFO_MAX - 1)
176+};
177+
178+enum {
179+ DRBD_A_START_OV_PARMS_OV_START_SECTOR = 1,
180+ DRBD_A_START_OV_PARMS_OV_STOP_SECTOR,
181+
182+ __DRBD_A_START_OV_PARMS_MAX,
183+ DRBD_A_START_OV_PARMS_MAX = (__DRBD_A_START_OV_PARMS_MAX - 1)
184+};
185+
186+enum {
187+ DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM = 1,
188+
189+ __DRBD_A_NEW_C_UUID_PARMS_MAX,
190+ DRBD_A_NEW_C_UUID_PARMS_MAX = (__DRBD_A_NEW_C_UUID_PARMS_MAX - 1)
191+};
192+
193+enum {
194+ DRBD_A_TIMEOUT_PARMS_TIMEOUT_TYPE = 1,
195+
196+ __DRBD_A_TIMEOUT_PARMS_MAX,
197+ DRBD_A_TIMEOUT_PARMS_MAX = (__DRBD_A_TIMEOUT_PARMS_MAX - 1)
198+};
199+
200+enum {
201+ DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT = 1,
202+
203+ __DRBD_A_DISCONNECT_PARMS_MAX,
204+ DRBD_A_DISCONNECT_PARMS_MAX = (__DRBD_A_DISCONNECT_PARMS_MAX - 1)
205+};
206+
207+enum {
208+ DRBD_A_DETACH_PARMS_FORCE_DETACH = 1,
209+
210+ __DRBD_A_DETACH_PARMS_MAX,
211+ DRBD_A_DETACH_PARMS_MAX = (__DRBD_A_DETACH_PARMS_MAX - 1)
212+};
213+
214+enum {
215+ DRBD_A_RESOURCE_INFO_RES_ROLE = 1,
216+ DRBD_A_RESOURCE_INFO_RES_SUSP,
217+ DRBD_A_RESOURCE_INFO_RES_SUSP_NOD,
218+ DRBD_A_RESOURCE_INFO_RES_SUSP_FEN,
219+
220+ __DRBD_A_RESOURCE_INFO_MAX,
221+ DRBD_A_RESOURCE_INFO_MAX = (__DRBD_A_RESOURCE_INFO_MAX - 1)
222+};
223+
224+enum {
225+ DRBD_A_DEVICE_INFO_DEV_DISK_STATE = 1,
226+
227+ __DRBD_A_DEVICE_INFO_MAX,
228+ DRBD_A_DEVICE_INFO_MAX = (__DRBD_A_DEVICE_INFO_MAX - 1)
229+};
230+
231+enum {
232+ DRBD_A_CONNECTION_INFO_CONN_CONNECTION_STATE = 1,
233+ DRBD_A_CONNECTION_INFO_CONN_ROLE,
234+
235+ __DRBD_A_CONNECTION_INFO_MAX,
236+ DRBD_A_CONNECTION_INFO_MAX = (__DRBD_A_CONNECTION_INFO_MAX - 1)
237+};
238+
239+enum {
240+ DRBD_A_PEER_DEVICE_INFO_PEER_REPL_STATE = 1,
241+ DRBD_A_PEER_DEVICE_INFO_PEER_DISK_STATE,
242+ DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_USER,
243+ DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_PEER,
244+ DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY,
245+
246+ __DRBD_A_PEER_DEVICE_INFO_MAX,
247+ DRBD_A_PEER_DEVICE_INFO_MAX = (__DRBD_A_PEER_DEVICE_INFO_MAX - 1)
248+};
249+
250+enum {
251+ DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING = 1,
252+
253+ __DRBD_A_RESOURCE_STATISTICS_MAX,
254+ DRBD_A_RESOURCE_STATISTICS_MAX = (__DRBD_A_RESOURCE_STATISTICS_MAX - 1)
255+};
256+
257+enum {
258+ DRBD_A_DEVICE_STATISTICS_DEV_SIZE = 1,
259+ DRBD_A_DEVICE_STATISTICS_DEV_READ,
260+ DRBD_A_DEVICE_STATISTICS_DEV_WRITE,
261+ DRBD_A_DEVICE_STATISTICS_DEV_AL_WRITES,
262+ DRBD_A_DEVICE_STATISTICS_DEV_BM_WRITES,
263+ DRBD_A_DEVICE_STATISTICS_DEV_UPPER_PENDING,
264+ DRBD_A_DEVICE_STATISTICS_DEV_LOWER_PENDING,
265+ DRBD_A_DEVICE_STATISTICS_DEV_UPPER_BLOCKED,
266+ DRBD_A_DEVICE_STATISTICS_DEV_LOWER_BLOCKED,
267+ DRBD_A_DEVICE_STATISTICS_DEV_AL_SUSPENDED,
268+ DRBD_A_DEVICE_STATISTICS_DEV_EXPOSED_DATA_UUID,
269+ DRBD_A_DEVICE_STATISTICS_DEV_CURRENT_UUID,
270+ DRBD_A_DEVICE_STATISTICS_DEV_DISK_FLAGS,
271+ DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS,
272+
273+ __DRBD_A_DEVICE_STATISTICS_MAX,
274+ DRBD_A_DEVICE_STATISTICS_MAX = (__DRBD_A_DEVICE_STATISTICS_MAX - 1)
275+};
276+
277+enum {
278+ DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED = 1,
279+
280+ __DRBD_A_CONNECTION_STATISTICS_MAX,
281+ DRBD_A_CONNECTION_STATISTICS_MAX = (__DRBD_A_CONNECTION_STATISTICS_MAX - 1)
282+};
283+
284+enum {
285+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RECEIVED = 1,
286+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_SENT,
287+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_PENDING,
288+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_UNACKED,
289+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_OUT_OF_SYNC,
290+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_RESYNC_FAILED,
291+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_BITMAP_UUID,
292+ DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS = 9,
293+
294+ __DRBD_A_PEER_DEVICE_STATISTICS_MAX,
295+ DRBD_A_PEER_DEVICE_STATISTICS_MAX = (__DRBD_A_PEER_DEVICE_STATISTICS_MAX - 1)
296+};
297+
298+enum {
299+ DRBD_A_DRBD_NOTIFICATION_HEADER_NH_TYPE = 1,
300+
301+ __DRBD_A_DRBD_NOTIFICATION_HEADER_MAX,
302+ DRBD_A_DRBD_NOTIFICATION_HEADER_MAX = (__DRBD_A_DRBD_NOTIFICATION_HEADER_MAX - 1)
303+};
304+
305+enum {
306+ DRBD_A_DRBD_HELPER_INFO_HELPER_NAME = 1,
307+ DRBD_A_DRBD_HELPER_INFO_HELPER_STATUS,
308+
309+ __DRBD_A_DRBD_HELPER_INFO_MAX,
310+ DRBD_A_DRBD_HELPER_INFO_MAX = (__DRBD_A_DRBD_HELPER_INFO_MAX - 1)
311+};
312+
313+enum {
314+ DRBD_ADM_EVENT = 1,
315+ DRBD_ADM_GET_STATUS,
316+ DRBD_ADM_NEW_MINOR = 5,
317+ DRBD_ADM_DEL_MINOR,
318+ DRBD_ADM_NEW_RESOURCE,
319+ DRBD_ADM_DEL_RESOURCE,
320+ DRBD_ADM_RESOURCE_OPTS,
321+ DRBD_ADM_CONNECT,
322+ DRBD_ADM_DISCONNECT,
323+ DRBD_ADM_ATTACH,
324+ DRBD_ADM_RESIZE,
325+ DRBD_ADM_PRIMARY,
326+ DRBD_ADM_SECONDARY,
327+ DRBD_ADM_NEW_C_UUID,
328+ DRBD_ADM_START_OV,
329+ DRBD_ADM_DETACH,
330+ DRBD_ADM_INVALIDATE,
331+ DRBD_ADM_INVAL_PEER,
332+ DRBD_ADM_PAUSE_SYNC,
333+ DRBD_ADM_RESUME_SYNC,
334+ DRBD_ADM_SUSPEND_IO,
335+ DRBD_ADM_RESUME_IO,
336+ DRBD_ADM_OUTDATE,
337+ DRBD_ADM_GET_TIMEOUT_TYPE,
338+ DRBD_ADM_DOWN,
339+ DRBD_ADM_CHG_DISK_OPTS,
340+ DRBD_ADM_CHG_NET_OPTS,
341+ DRBD_ADM_GET_RESOURCES,
342+ DRBD_ADM_GET_DEVICES,
343+ DRBD_ADM_GET_CONNECTIONS,
344+ DRBD_ADM_GET_PEER_DEVICES,
345+ DRBD_ADM_RESOURCE_STATE,
346+ DRBD_ADM_DEVICE_STATE,
347+ DRBD_ADM_CONNECTION_STATE,
348+ DRBD_ADM_PEER_DEVICE_STATE,
349+ DRBD_ADM_GET_INITIAL_STATE,
350+ DRBD_ADM_HELPER = 40,
351+ DRBD_ADM_INITIAL_STATE_DONE,
352+
353+ __DRBD_ADM_MAX,
354+ DRBD_ADM_MAX = (__DRBD_ADM_MAX - 1)
355+};
356+
357+#define DRBD_MCGRP_EVENTS "events"
358+
359+#endif /* _UAPI_LINUX_DRBD_GENL_H */