Two new handlers have been defined in genl_magic_ headers:
 - __field2: the corresponding nla_put() function (nla_put_flag()) takes
             only two args
 - __field4: the corresponding nla_put() function (nla_put_u64_64bit())
             takes four args

__field2 allows us to define __unspec_field for padding attribute.
__field4 allows us to update the definition of __u64_field: the pad
attribute should now be specified.

Note that this patch is only compile-tested.

Signed-off-by: Nicolas Dichtel <nicolas.dich...@6wind.com>
---

v1 -> v2:
 rework the patch to handle all cases

 drivers/block/drbd/drbd_nl.c      | 40 +++++++++++++++++--------
 include/linux/drbd_genl.h         | 62 +++++++++++++++++++++------------------
 include/linux/genl_magic_func.h   | 41 ++++++++++++++++++++++++++
 include/linux/genl_magic_struct.h | 45 ++++++++++++++++++++++++++--
 4 files changed, 145 insertions(+), 43 deletions(-)

diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 1fd1dccebb6b..93d873532195 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -3633,14 +3633,23 @@ static int nla_put_status_info(struct sk_buff *skb, 
struct drbd_device *device,
                goto nla_put_failure;
        if (nla_put_u32(skb, T_sib_reason, sib ? sib->sib_reason : 
SIB_GET_STATUS_REPLY) ||
            nla_put_u32(skb, T_current_state, device->state.i) ||
-           nla_put_u64(skb, T_ed_uuid, device->ed_uuid) ||
-           nla_put_u64(skb, T_capacity, drbd_get_capacity(device->this_bdev)) 
||
-           nla_put_u64(skb, T_send_cnt, device->send_cnt) ||
-           nla_put_u64(skb, T_recv_cnt, device->recv_cnt) ||
-           nla_put_u64(skb, T_read_cnt, device->read_cnt) ||
-           nla_put_u64(skb, T_writ_cnt, device->writ_cnt) ||
-           nla_put_u64(skb, T_al_writ_cnt, device->al_writ_cnt) ||
-           nla_put_u64(skb, T_bm_writ_cnt, device->bm_writ_cnt) ||
+           nla_put_u64_64bit(skb, T_ed_uuid, device->ed_uuid,
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_capacity,
+                             drbd_get_capacity(device->this_bdev),
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_send_cnt, device->send_cnt,
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_recv_cnt, device->recv_cnt,
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_read_cnt, device->read_cnt,
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_writ_cnt, device->writ_cnt,
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_al_writ_cnt, device->al_writ_cnt,
+                             T_state_info_pad) ||
+           nla_put_u64_64bit(skb, T_bm_writ_cnt, device->bm_writ_cnt,
+                             T_state_info_pad) ||
            nla_put_u32(skb, T_ap_bio_cnt, atomic_read(&device->ap_bio_cnt)) ||
            nla_put_u32(skb, T_ap_pending_cnt, 
atomic_read(&device->ap_pending_cnt)) ||
            nla_put_u32(skb, T_rs_pending_cnt, 
atomic_read(&device->rs_pending_cnt)))
@@ -3657,13 +3666,20 @@ static int nla_put_status_info(struct sk_buff *skb, 
struct drbd_device *device,
                        goto nla_put_failure;
 
                if (nla_put_u32(skb, T_disk_flags, device->ldev->md.flags) ||
-                   nla_put_u64(skb, T_bits_total, drbd_bm_bits(device)) ||
-                   nla_put_u64(skb, T_bits_oos, drbd_bm_total_weight(device)))
+                   nla_put_u64_64bit(skb, T_bits_total, drbd_bm_bits(device),
+                                     T_state_info_pad) ||
+                   nla_put_u64_64bit(skb, T_bits_oos,
+                                     drbd_bm_total_weight(device),
+                                     T_state_info_pad))
                        goto nla_put_failure;
                if (C_SYNC_SOURCE <= device->state.conn &&
                    C_PAUSED_SYNC_T >= device->state.conn) {
-                       if (nla_put_u64(skb, T_bits_rs_total, device->rs_total) 
||
-                           nla_put_u64(skb, T_bits_rs_failed, 
device->rs_failed))
+                       if (nla_put_u64_64bit(skb, T_bits_rs_total,
+                                             device->rs_total,
+                                             T_state_info_pad) ||
+                           nla_put_u64_64bit(skb, T_bits_rs_failed,
+                                             device->rs_failed,
+                                             T_state_info_pad))
                                goto nla_put_failure;
                }
        }
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 2d0e5ad5de9d..f3b810089142 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -107,7 +107,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
        __s32_field(3, DRBD_F_REQUIRED | DRBD_F_INVARIANT,      meta_dev_idx)
 
        /* use the resize command to try and change the disk_size */
-       __u64_field(4, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT,       
disk_size)
+       __u64_field(4, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT,       
disk_size, 24)
        /* we could change the max_bio_bvecs,
         * but it won't propagate through the stack */
        __u32_field(5, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT,       
max_bio_bvecs)
@@ -132,6 +132,7 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
        __u32_field_def(21,     0 /* OPTIONAL */,       read_balancing, 
DRBD_READ_BALANCING_DEF)
        /* 9: __u32_field_def(22,       DRBD_GENLA_F_MANDATORY, 
unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF) */
        __flg_field_def(23,     0 /* OPTIONAL */,       al_updates, 
DRBD_AL_UPDATES_DEF)
+       __unspec_field(24,      0               ,       disk_conf_pad)
 )
 
 GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts,
@@ -182,11 +183,12 @@ GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms,
 )
 
 GENL_struct(DRBD_NLA_RESIZE_PARMS, 7, resize_parms,
-       __u64_field(1, DRBD_GENLA_F_MANDATORY,  resize_size)
+       __u64_field(1, DRBD_GENLA_F_MANDATORY,  resize_size, 6)
        __flg_field(2, DRBD_GENLA_F_MANDATORY,  resize_force)
        __flg_field(3, DRBD_GENLA_F_MANDATORY,  no_resync)
        __u32_field_def(4, 0 /* OPTIONAL */, al_stripes, DRBD_AL_STRIPES_DEF)
        __u32_field_def(5, 0 /* OPTIONAL */, al_stripe_size, 
DRBD_AL_STRIPE_SIZE_DEF)
+       __unspec_field(6, 0, resize_parms_pad)
 )
 
 GENL_struct(DRBD_NLA_STATE_INFO, 8, state_info,
@@ -194,8 +196,8 @@ GENL_struct(DRBD_NLA_STATE_INFO, 8, state_info,
         * if this is an event triggered broadcast. */
        __u32_field(1, DRBD_GENLA_F_MANDATORY,  sib_reason)
        __u32_field(2, DRBD_F_REQUIRED, current_state)
-       __u64_field(3, DRBD_GENLA_F_MANDATORY,  capacity)
-       __u64_field(4, DRBD_GENLA_F_MANDATORY,  ed_uuid)
+       __u64_field(3, DRBD_GENLA_F_MANDATORY,  capacity, 24)
+       __u64_field(4, DRBD_GENLA_F_MANDATORY,  ed_uuid, 24)
 
        /* These are for broadcast from after state change work.
         * prev_state and new_state are from the moment the state change took
@@ -208,30 +210,32 @@ GENL_struct(DRBD_NLA_STATE_INFO, 8, state_info,
        /* if we have a local disk: */
        __bin_field(7, DRBD_GENLA_F_MANDATORY,  uuids, (UI_SIZE*sizeof(__u64)))
        __u32_field(8, DRBD_GENLA_F_MANDATORY,  disk_flags)
-       __u64_field(9, DRBD_GENLA_F_MANDATORY,  bits_total)
-       __u64_field(10, DRBD_GENLA_F_MANDATORY, bits_oos)
+       __u64_field(9, DRBD_GENLA_F_MANDATORY,  bits_total, 24)
+       __u64_field(10, DRBD_GENLA_F_MANDATORY, bits_oos, 24)
        /* and in case resync or online verify is active */
-       __u64_field(11, DRBD_GENLA_F_MANDATORY, bits_rs_total)
-       __u64_field(12, DRBD_GENLA_F_MANDATORY, bits_rs_failed)
+       __u64_field(11, DRBD_GENLA_F_MANDATORY, bits_rs_total, 24)
+       __u64_field(12, DRBD_GENLA_F_MANDATORY, bits_rs_failed, 24)
 
        /* for pre and post notifications of helper execution */
        __str_field(13, DRBD_GENLA_F_MANDATORY, helper, 32)
        __u32_field(14, DRBD_GENLA_F_MANDATORY, helper_exit_code)
 
-       __u64_field(15,                      0, send_cnt)
-       __u64_field(16,                      0, recv_cnt)
-       __u64_field(17,                      0, read_cnt)
-       __u64_field(18,                      0, writ_cnt)
-       __u64_field(19,                      0, al_writ_cnt)
-       __u64_field(20,                      0, bm_writ_cnt)
+       __u64_field(15,                      0, send_cnt, 24)
+       __u64_field(16,                      0, recv_cnt, 24)
+       __u64_field(17,                      0, read_cnt, 24)
+       __u64_field(18,                      0, writ_cnt, 24)
+       __u64_field(19,                      0, al_writ_cnt, 24)
+       __u64_field(20,                      0, bm_writ_cnt, 24)
        __u32_field(21,                      0, ap_bio_cnt)
        __u32_field(22,                      0, ap_pending_cnt)
        __u32_field(23,                      0, rs_pending_cnt)
+       __unspec_field(24,                   0, state_info_pad)
 )
 
 GENL_struct(DRBD_NLA_START_OV_PARMS, 9, start_ov_parms,
-       __u64_field(1, DRBD_GENLA_F_MANDATORY,  ov_start_sector)
-       __u64_field(2, DRBD_GENLA_F_MANDATORY,  ov_stop_sector)
+       __u64_field(1, DRBD_GENLA_F_MANDATORY,  ov_start_sector, 3)
+       __u64_field(2, DRBD_GENLA_F_MANDATORY,  ov_stop_sector, 3)
+       __unspec_field(3, 0, ov_pad)
 )
 
 GENL_struct(DRBD_NLA_NEW_C_UUID_PARMS, 10, new_c_uuid_parms,
@@ -280,20 +284,21 @@ GENL_struct(DRBD_NLA_RESOURCE_STATISTICS, 19, 
resource_statistics,
 )
 
 GENL_struct(DRBD_NLA_DEVICE_STATISTICS, 20, device_statistics,
-       __u64_field(1, 0, dev_size)  /* (sectors) */
-       __u64_field(2, 0, dev_read)  /* (sectors) */
-       __u64_field(3, 0, dev_write)  /* (sectors) */
-       __u64_field(4, 0, dev_al_writes)  /* activity log writes (count) */
-       __u64_field(5, 0, dev_bm_writes)  /*  bitmap writes  (count) */
+       __u64_field(1, 0, dev_size, 15)  /* (sectors) */
+       __u64_field(2, 0, dev_read, 15)  /* (sectors) */
+       __u64_field(3, 0, dev_write, 15)  /* (sectors) */
+       __u64_field(4, 0, dev_al_writes, 15)  /* activity log writes (count) */
+       __u64_field(5, 0, dev_bm_writes, 15)  /*  bitmap writes  (count) */
        __u32_field(6, 0, dev_upper_pending)  /* application requests in 
progress */
        __u32_field(7, 0, dev_lower_pending)  /* backing device requests in 
progress */
        __flg_field(8, 0, dev_upper_blocked)
        __flg_field(9, 0, dev_lower_blocked)
        __flg_field(10, 0, dev_al_suspended)  /* activity log suspended */
-       __u64_field(11, 0, dev_exposed_data_uuid)
-       __u64_field(12, 0, dev_current_uuid)
+       __u64_field(11, 0, dev_exposed_data_uuid, 15)
+       __u64_field(12, 0, dev_current_uuid, 15)
        __u32_field(13, 0, dev_disk_flags)
        __bin_field(14, 0, history_uuids, HISTORY_UUIDS * sizeof(__u64))
+       __unspec_field(15, 0, dev_pad)
 )
 
 GENL_struct(DRBD_NLA_CONNECTION_STATISTICS, 21, connection_statistics,
@@ -301,14 +306,15 @@ GENL_struct(DRBD_NLA_CONNECTION_STATISTICS, 21, 
connection_statistics,
 )
 
 GENL_struct(DRBD_NLA_PEER_DEVICE_STATISTICS, 22, peer_device_statistics,
-       __u64_field(1, 0, peer_dev_received)  /* sectors */
-       __u64_field(2, 0, peer_dev_sent)  /* sectors */
+       __u64_field(1, 0, peer_dev_received, 10)  /* sectors */
+       __u64_field(2, 0, peer_dev_sent, 10)  /* sectors */
        __u32_field(3, 0, peer_dev_pending)  /* number of requests */
        __u32_field(4, 0, peer_dev_unacked)  /* number of requests */
-       __u64_field(5, 0, peer_dev_out_of_sync)  /* sectors */
-       __u64_field(6, 0, peer_dev_resync_failed)  /* sectors */
-       __u64_field(7, 0, peer_dev_bitmap_uuid)
+       __u64_field(5, 0, peer_dev_out_of_sync, 10)  /* sectors */
+       __u64_field(6, 0, peer_dev_resync_failed, 10)  /* sectors */
+       __u64_field(7, 0, peer_dev_bitmap_uuid, 10)
        __u32_field(9, 0, peer_dev_flags)
+       __unspec_field(10, 0, peer_dev_pad)
 )
 
 GENL_struct(DRBD_NLA_NOTIFICATION_HEADER, 23, drbd_notification_header,
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
index 667c31101b8b..34b12f0836a5 100644
--- a/include/linux/genl_magic_func.h
+++ b/include/linux/genl_magic_func.h
@@ -35,6 +35,15 @@ static struct nla_policy s_name ## _nl_policy[] 
__read_mostly =              \
                 __put, __is_signed)                                    \
        [attr_nr] = { .type = nla_type },
 
+#undef __field2
+#define __field2 __field
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, _type, __get,     \
+                __put, __is_signed, padattr)                           \
+       __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
+               __put, __is_signed)
+
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen,     \
                __get, __put, __is_signed)                              \
@@ -199,6 +208,15 @@ static int s_name ## _from_attrs_for_change(struct s_name 
*s,              \
                                s->name = __get(nla);                   \
                        DPRINT_FIELD("<<", nla_type, name, s, nla))
 
+#undef __field2
+#define __field2 __field
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, _type, __get,     \
+                __put, __is_signed, padattr)                           \
+       __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
+               __put, __is_signed)
+
 /* validate_nla() already checked nla_len <= maxlen appropriately. */
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,      \
@@ -362,6 +380,24 @@ static inline int s_name ## _to_unpriv_skb(struct sk_buff 
*skb,            \
                        goto nla_put_failure;                           \
        }
 
+#undef __field2
+#define __field2(attr_nr, attr_flag, name, nla_type, type, __get, __put,\
+                __is_signed)                                           \
+       if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {  \
+               DPRINT_FIELD(">>", nla_type, name, s, NULL);            \
+               if (__put(skb, attr_nr))                                \
+                       goto nla_put_failure;                           \
+       }
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, type, __get, __put,\
+                __is_signed, padattr)                                  \
+       if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {  \
+               DPRINT_FIELD(">>", nla_type, name, s, NULL);            \
+               if (__put(skb, attr_nr, s->name, padattr))              \
+                       goto nla_put_failure;                           \
+       }
+
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,      \
                __get, __put, __is_signed)                              \
@@ -381,6 +417,11 @@ static inline int s_name ## _to_unpriv_skb(struct sk_buff 
*skb,            \
 #undef __field
 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put,        
\
                __is_signed)
+#undef __field2
+#define __field2 __field
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, type, __get, __put,\
+               __is_signed, padattr)
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,      \
                __get, __put, __is_signed)
diff --git a/include/linux/genl_magic_struct.h 
b/include/linux/genl_magic_struct.h
index eecd19b37001..768e63406540 100644
--- a/include/linux/genl_magic_struct.h
+++ b/include/linux/genl_magic_struct.h
@@ -66,6 +66,9 @@ extern void CONCAT_(GENL_MAGIC_FAMILY, 
_genl_unregister)(void);
 #define __flg_field(attr_nr, attr_flag, name) \
        __field(attr_nr, attr_flag, name, NLA_U8, char, \
                        nla_get_u8, nla_put_u8, false)
+#define __unspec_field(attr_nr, attr_flag, name)       \
+       __field2(attr_nr, attr_flag, name, NLA_UNSPEC, unsigned char, \
+                       nla_get_flag, nla_put_flag, false)
 #define __u8_field(attr_nr, attr_flag, name)   \
        __field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \
                        nla_get_u8, nla_put_u8, false)
@@ -78,9 +81,9 @@ extern void CONCAT_(GENL_MAGIC_FAMILY, 
_genl_unregister)(void);
 #define __s32_field(attr_nr, attr_flag, name)  \
        __field(attr_nr, attr_flag, name, NLA_U32, __s32, \
                        nla_get_u32, nla_put_u32, true)
-#define __u64_field(attr_nr, attr_flag, name)  \
-       __field(attr_nr, attr_flag, name, NLA_U64, __u64, \
-                       nla_get_u64, nla_put_u64, false)
+#define __u64_field(attr_nr, attr_flag, name, padattr) \
+       __field4(attr_nr, attr_flag, name, NLA_U64, __u64, \
+                       nla_get_u64, nla_put_u64_64bit, false, padattr)
 #define __str_field(attr_nr, attr_flag, name, maxlen) \
        __array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \
                        nla_strlcpy, nla_put, false)
@@ -156,6 +159,15 @@ enum {                                                     
        \
                __get, __put, __is_signed)                      \
        T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)),
 
+#undef __field2
+#define __field2 __field
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, _type, __get,     \
+                __put, __is_signed, padattr)                           \
+       __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
+               __put, __is_signed)
+
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type,      \
                maxlen, __get, __put, __is_signed)              \
@@ -222,6 +234,15 @@ static inline void ct_assert_unique_ ## s_name ## 
_attributes(void)        \
                __is_signed)                                            \
        case attr_nr:
 
+#undef __field2
+#define __field2 __field
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, _type, __get,     \
+                __put, __is_signed, padattr)                           \
+       __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
+               __put, __is_signed)
+
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,      \
                __get, __put, __is_signed)                              \
@@ -246,6 +267,15 @@ struct s_name { s_fields };
                __is_signed)                                            \
        type name;
 
+#undef __field2
+#define __field2 __field
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, _type, __get,     \
+                __put, __is_signed, padattr)                           \
+       __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
+               __put, __is_signed)
+
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,      \
                __get, __put, __is_signed)                              \
@@ -265,6 +295,15 @@ enum {                                                     
                \
                is_signed)                                              \
        F_ ## name ## _IS_SIGNED = is_signed,
 
+#undef __field2
+#define __field2 __field
+
+#undef __field4
+#define __field4(attr_nr, attr_flag, name, nla_type, _type, __get,     \
+                __put, __is_signed, padattr)                           \
+       __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
+               __put, __is_signed)
+
 #undef __array
 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,      \
                __get, __put, is_signed)                                \
-- 
2.8.1

Reply via email to