diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-06-10 06:57:26 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:57:45 -0500 |
commit | 01b39b50d34733646fe46a582fa60d3b53f6180d (patch) | |
tree | 1602650bce908e1b65b656070be7473948001255 /drivers/block/drbd | |
parent | 7c3063cc6f0e75cdf312f5f318f9a4c02e460397 (diff) |
drbd: Split off netlink mandatory attribute handling into separate file
Duplicate this file in the kernel module and in user space; both sides need it.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/Makefile | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 51 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nla.c | 55 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nla.h | 8 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_wrappers.h | 1 |
6 files changed, 66 insertions, 56 deletions
diff --git a/drivers/block/drbd/Makefile b/drivers/block/drbd/Makefile index 06fb4453734c..8b450338075e 100644 --- a/drivers/block/drbd/Makefile +++ b/drivers/block/drbd/Makefile | |||
@@ -2,5 +2,6 @@ drbd-y := drbd_bitmap.o drbd_proc.o | |||
2 | drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o | 2 | drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o |
3 | drbd-y += drbd_main.o drbd_strings.o drbd_nl.o | 3 | drbd-y += drbd_main.o drbd_strings.o drbd_nl.o |
4 | drbd-y += drbd_interval.o drbd_state.o | 4 | drbd-y += drbd_interval.o drbd_state.o |
5 | drbd-y += drbd_nla.o | ||
5 | 6 | ||
6 | obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o | 7 | obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c58430183d5f..c3019730a24f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1407,12 +1407,6 @@ extern bool conn_try_outdate_peer(struct drbd_tconn *tconn); | |||
1407 | extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn); | 1407 | extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn); |
1408 | extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); | 1408 | extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); |
1409 | 1409 | ||
1410 | struct nla_policy; | ||
1411 | extern int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla); | ||
1412 | extern int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, | ||
1413 | const struct nla_policy *policy); | ||
1414 | extern struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype); | ||
1415 | |||
1416 | /* drbd_worker.c */ | 1410 | /* drbd_worker.c */ |
1417 | extern int drbd_worker(struct drbd_thread *thi); | 1411 | extern int drbd_worker(struct drbd_thread *thi); |
1418 | enum drbd_ret_code drbd_resync_after_valid(struct drbd_conf *mdev, int o_minor); | 1412 | enum drbd_ret_code drbd_resync_after_valid(struct drbd_conf *mdev, int o_minor); |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 24187f1c93d5..45bb5cebb59d 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -75,6 +75,7 @@ int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info); | |||
75 | int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb); | 75 | int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb); |
76 | 76 | ||
77 | #include <linux/drbd_genl_api.h> | 77 | #include <linux/drbd_genl_api.h> |
78 | #include "drbd_nla.h" | ||
78 | #include <linux/genl_magic_func.h> | 79 | #include <linux/genl_magic_func.h> |
79 | 80 | ||
80 | /* used blkdev_get_by_path, to claim our meta data device(s) */ | 81 | /* used blkdev_get_by_path, to claim our meta data device(s) */ |
@@ -3219,53 +3220,3 @@ failed: | |||
3219 | "Event seq:%u sib_reason:%u\n", | 3220 | "Event seq:%u sib_reason:%u\n", |
3220 | err, seq, sib->sib_reason); | 3221 | err, seq, sib->sib_reason); |
3221 | } | 3222 | } |
3222 | |||
3223 | int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla) | ||
3224 | { | ||
3225 | struct nlattr *head = nla_data(nla); | ||
3226 | int len = nla_len(nla); | ||
3227 | int rem; | ||
3228 | |||
3229 | /* | ||
3230 | * validate_nla (called from nla_parse_nested) ignores attributes | ||
3231 | * beyond maxtype, and does not understand the DRBD_GENLA_F_MANDATORY flag. | ||
3232 | * In order to have it validate attributes with the DRBD_GENLA_F_MANDATORY | ||
3233 | * flag set also, check and remove that flag before calling | ||
3234 | * nla_parse_nested. | ||
3235 | */ | ||
3236 | |||
3237 | nla_for_each_attr(nla, head, len, rem) { | ||
3238 | if (nla->nla_type & DRBD_GENLA_F_MANDATORY) { | ||
3239 | nla->nla_type &= ~DRBD_GENLA_F_MANDATORY; | ||
3240 | if (nla_type(nla) > maxtype) | ||
3241 | return -EOPNOTSUPP; | ||
3242 | } | ||
3243 | } | ||
3244 | return 0; | ||
3245 | } | ||
3246 | |||
3247 | int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, | ||
3248 | const struct nla_policy *policy) | ||
3249 | { | ||
3250 | int err; | ||
3251 | |||
3252 | err = drbd_nla_check_mandatory(maxtype, nla); | ||
3253 | if (!err) | ||
3254 | err = nla_parse_nested(tb, maxtype, nla, policy); | ||
3255 | |||
3256 | return err; | ||
3257 | } | ||
3258 | |||
3259 | struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype) | ||
3260 | { | ||
3261 | int err; | ||
3262 | /* | ||
3263 | * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and | ||
3264 | * we don't know about that attribute, reject all the nested | ||
3265 | * attributes. | ||
3266 | */ | ||
3267 | err = drbd_nla_check_mandatory(maxtype, nla); | ||
3268 | if (err) | ||
3269 | return ERR_PTR(err); | ||
3270 | return nla_find_nested(nla, attrtype); | ||
3271 | } | ||
diff --git a/drivers/block/drbd/drbd_nla.c b/drivers/block/drbd/drbd_nla.c new file mode 100644 index 000000000000..fa672b6df8d6 --- /dev/null +++ b/drivers/block/drbd/drbd_nla.c | |||
@@ -0,0 +1,55 @@ | |||
1 | #include "drbd_wrappers.h" | ||
2 | #include <linux/kernel.h> | ||
3 | #include <net/netlink.h> | ||
4 | #include <linux/drbd_genl_api.h> | ||
5 | #include "drbd_nla.h" | ||
6 | |||
7 | static int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla) | ||
8 | { | ||
9 | struct nlattr *head = nla_data(nla); | ||
10 | int len = nla_len(nla); | ||
11 | int rem; | ||
12 | |||
13 | /* | ||
14 | * validate_nla (called from nla_parse_nested) ignores attributes | ||
15 | * beyond maxtype, and does not understand the DRBD_GENLA_F_MANDATORY flag. | ||
16 | * In order to have it validate attributes with the DRBD_GENLA_F_MANDATORY | ||
17 | * flag set also, check and remove that flag before calling | ||
18 | * nla_parse_nested. | ||
19 | */ | ||
20 | |||
21 | nla_for_each_attr(nla, head, len, rem) { | ||
22 | if (nla->nla_type & DRBD_GENLA_F_MANDATORY) { | ||
23 | nla->nla_type &= ~DRBD_GENLA_F_MANDATORY; | ||
24 | if (nla_type(nla) > maxtype) | ||
25 | return -EOPNOTSUPP; | ||
26 | } | ||
27 | } | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, | ||
32 | const struct nla_policy *policy) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | err = drbd_nla_check_mandatory(maxtype, nla); | ||
37 | if (!err) | ||
38 | err = nla_parse_nested(tb, maxtype, nla, policy); | ||
39 | |||
40 | return err; | ||
41 | } | ||
42 | |||
43 | struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype) | ||
44 | { | ||
45 | int err; | ||
46 | /* | ||
47 | * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and | ||
48 | * we don't know about that attribute, reject all the nested | ||
49 | * attributes. | ||
50 | */ | ||
51 | err = drbd_nla_check_mandatory(maxtype, nla); | ||
52 | if (err) | ||
53 | return ERR_PTR(err); | ||
54 | return nla_find_nested(nla, attrtype); | ||
55 | } | ||
diff --git a/drivers/block/drbd/drbd_nla.h b/drivers/block/drbd/drbd_nla.h new file mode 100644 index 000000000000..679c2d5b4535 --- /dev/null +++ b/drivers/block/drbd/drbd_nla.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef __DRBD_NLA_H | ||
2 | #define __DRBD_NLA_H | ||
3 | |||
4 | extern int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, | ||
5 | const struct nla_policy *policy); | ||
6 | extern struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype); | ||
7 | |||
8 | #endif /* __DRBD_NLA_H */ | ||
diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h index 46a6d99f7b61..328f18e4b4ee 100644 --- a/drivers/block/drbd/drbd_wrappers.h +++ b/drivers/block/drbd/drbd_wrappers.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/ctype.h> | 4 | #include <linux/ctype.h> |
5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
6 | #include "drbd_int.h" | ||
6 | 7 | ||
7 | /* see get_sb_bdev and bd_claim */ | 8 | /* see get_sb_bdev and bd_claim */ |
8 | extern char *drbd_sec_holder; | 9 | extern char *drbd_sec_holder; |