aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-06-10 06:57:26 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:57:45 -0500
commit01b39b50d34733646fe46a582fa60d3b53f6180d (patch)
tree1602650bce908e1b65b656070be7473948001255 /drivers
parent7c3063cc6f0e75cdf312f5f318f9a4c02e460397 (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')
-rw-r--r--drivers/block/drbd/Makefile1
-rw-r--r--drivers/block/drbd/drbd_int.h6
-rw-r--r--drivers/block/drbd/drbd_nl.c51
-rw-r--r--drivers/block/drbd/drbd_nla.c55
-rw-r--r--drivers/block/drbd/drbd_nla.h8
-rw-r--r--drivers/block/drbd/drbd_wrappers.h1
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
2drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o 2drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
3drbd-y += drbd_main.o drbd_strings.o drbd_nl.o 3drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
4drbd-y += drbd_interval.o drbd_state.o 4drbd-y += drbd_interval.o drbd_state.o
5drbd-y += drbd_nla.o
5 6
6obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o 7obj-$(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);
1407extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn); 1407extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn);
1408extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); 1408extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);
1409 1409
1410struct nla_policy;
1411extern int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla);
1412extern int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
1413 const struct nla_policy *policy);
1414extern struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype);
1415
1416/* drbd_worker.c */ 1410/* drbd_worker.c */
1417extern int drbd_worker(struct drbd_thread *thi); 1411extern int drbd_worker(struct drbd_thread *thi);
1418enum drbd_ret_code drbd_resync_after_valid(struct drbd_conf *mdev, int o_minor); 1412enum 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);
75int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb); 75int 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
3223int 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
3247int 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
3259struct 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
7static 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
31int 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
43struct 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
4extern int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
5 const struct nla_policy *policy);
6extern 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 */
8extern char *drbd_sec_holder; 9extern char *drbd_sec_holder;