diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-10-04 15:14:03 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-05 13:35:30 -0400 |
commit | ff4c92d85c6f2777d2067f8552e7fefb4d1754ae (patch) | |
tree | 77e35603821e5602e96c90644e42e70f097ad79c /net/netlink/genetlink.c | |
parent | 2ee4e27cf25ab647137713ca16377d8d9e138ea2 (diff) |
genetlink: introduce pre_doit/post_doit hooks
Each family may have some amount of boilerplate
locking code that applies to most, or even all,
commands.
This allows a family to handle such things in
a more generic way, by allowing it to
a) include private flags in each operation
b) specify a pre_doit hook that is called,
before an operation's doit() callback and
may return an error directly,
c) specify a post_doit hook that can undo
locking or similar things done by pre_doit,
and finally
d) include two private pointers in each info
struct passed between all these operations
including doit(). (It's two because I'll
need two in nl80211 -- can be extended.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r-- | net/netlink/genetlink.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 26ed3e8587c2..1781d99145e2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
547 | info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; | 547 | info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; |
548 | info.attrs = family->attrbuf; | 548 | info.attrs = family->attrbuf; |
549 | genl_info_net_set(&info, net); | 549 | genl_info_net_set(&info, net); |
550 | memset(&info.user_ptr, 0, sizeof(info.user_ptr)); | ||
550 | 551 | ||
551 | return ops->doit(skb, &info); | 552 | if (family->pre_doit) { |
553 | err = family->pre_doit(ops, skb, &info); | ||
554 | if (err) | ||
555 | return err; | ||
556 | } | ||
557 | |||
558 | err = ops->doit(skb, &info); | ||
559 | |||
560 | if (family->post_doit) | ||
561 | family->post_doit(ops, skb, &info); | ||
562 | |||
563 | return err; | ||
552 | } | 564 | } |
553 | 565 | ||
554 | static void genl_rcv(struct sk_buff *skb) | 566 | static void genl_rcv(struct sk_buff *skb) |