Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 01b39b50 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Philipp Reisner
Browse files

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 7c3063cc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,5 +2,6 @@ drbd-y := drbd_bitmap.o drbd_proc.o
drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
drbd-y += drbd_interval.o drbd_state.o
drbd-y += drbd_nla.o

obj-$(CONFIG_BLK_DEV_DRBD)     += drbd.o
+0 −6
Original line number Diff line number Diff line
@@ -1407,12 +1407,6 @@ extern bool conn_try_outdate_peer(struct drbd_tconn *tconn);
extern void conn_try_outdate_peer_async(struct drbd_tconn *tconn);
extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);

struct nla_policy;
extern int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla);
extern int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
				 const struct nla_policy *policy);
extern struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype);

/* drbd_worker.c */
extern int drbd_worker(struct drbd_thread *thi);
enum drbd_ret_code drbd_resync_after_valid(struct drbd_conf *mdev, int o_minor);
+1 −50
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info);
int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb);

#include <linux/drbd_genl_api.h>
#include "drbd_nla.h"
#include <linux/genl_magic_func.h>

/* used blkdev_get_by_path, to claim our meta data device(s) */
@@ -3219,53 +3220,3 @@ void drbd_bcast_event(struct drbd_conf *mdev, const struct sib_info *sib)
			"Event seq:%u sib_reason:%u\n",
			err, seq, sib->sib_reason);
}

int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla)
{
	struct nlattr *head = nla_data(nla);
	int len = nla_len(nla);
	int rem;

	/*
	 * validate_nla (called from nla_parse_nested) ignores attributes
	 * beyond maxtype, and does not understand the DRBD_GENLA_F_MANDATORY flag.
	 * In order to have it validate attributes with the DRBD_GENLA_F_MANDATORY
	 * flag set also, check and remove that flag before calling
	 * nla_parse_nested.
	 */

	nla_for_each_attr(nla, head, len, rem) {
		if (nla->nla_type & DRBD_GENLA_F_MANDATORY) {
			nla->nla_type &= ~DRBD_GENLA_F_MANDATORY;
			if (nla_type(nla) > maxtype)
				return -EOPNOTSUPP;
		}
	}
	return 0;
}

int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
			  const struct nla_policy *policy)
{
	int err;

	err = drbd_nla_check_mandatory(maxtype, nla);
	if (!err)
		err = nla_parse_nested(tb, maxtype, nla, policy);

	return err;
}

struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype)
{
	int err;
	/*
	 * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and
	 * we don't know about that attribute, reject all the nested
	 * attributes.
	 */
	err = drbd_nla_check_mandatory(maxtype, nla);
	if (err)
		return ERR_PTR(err);
	return nla_find_nested(nla, attrtype);
}
+55 −0
Original line number Diff line number Diff line
#include "drbd_wrappers.h"
#include <linux/kernel.h>
#include <net/netlink.h>
#include <linux/drbd_genl_api.h>
#include "drbd_nla.h"

static int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla)
{
	struct nlattr *head = nla_data(nla);
	int len = nla_len(nla);
	int rem;

	/*
	 * validate_nla (called from nla_parse_nested) ignores attributes
	 * beyond maxtype, and does not understand the DRBD_GENLA_F_MANDATORY flag.
	 * In order to have it validate attributes with the DRBD_GENLA_F_MANDATORY
	 * flag set also, check and remove that flag before calling
	 * nla_parse_nested.
	 */

	nla_for_each_attr(nla, head, len, rem) {
		if (nla->nla_type & DRBD_GENLA_F_MANDATORY) {
			nla->nla_type &= ~DRBD_GENLA_F_MANDATORY;
			if (nla_type(nla) > maxtype)
				return -EOPNOTSUPP;
		}
	}
	return 0;
}

int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
			  const struct nla_policy *policy)
{
	int err;

	err = drbd_nla_check_mandatory(maxtype, nla);
	if (!err)
		err = nla_parse_nested(tb, maxtype, nla, policy);

	return err;
}

struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype)
{
	int err;
	/*
	 * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and
	 * we don't know about that attribute, reject all the nested
	 * attributes.
	 */
	err = drbd_nla_check_mandatory(maxtype, nla);
	if (err)
		return ERR_PTR(err);
	return nla_find_nested(nla, attrtype);
}
+8 −0
Original line number Diff line number Diff line
#ifndef __DRBD_NLA_H
#define __DRBD_NLA_H

extern int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
				 const struct nla_policy *policy);
extern struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype);

#endif  /* __DRBD_NLA_H */
Loading