Linux Audio

Check our new training course

Loading...
v4.10.11
  1#include <linux/cred.h>
  2#include <linux/init.h>
  3#include <linux/kernel.h>
  4#include <linux/quotaops.h>
  5#include <linux/sched.h>
  6#include <linux/slab.h>
  7#include <net/netlink.h>
  8#include <net/genetlink.h>
  9
 10static const struct genl_multicast_group quota_mcgrps[] = {
 11	{ .name = "events", },
 12};
 13
 14/* Netlink family structure for quota */
 15static struct genl_family quota_genl_family __ro_after_init = {
 16	.module = THIS_MODULE,
 
 
 
 
 
 
 17	.hdrsize = 0,
 18	.name = "VFS_DQUOT",
 19	.version = 1,
 20	.maxattr = QUOTA_NL_A_MAX,
 21	.mcgrps = quota_mcgrps,
 22	.n_mcgrps = ARRAY_SIZE(quota_mcgrps),
 23};
 24
 25/**
 26 * quota_send_warning - Send warning to userspace about exceeded quota
 27 * @qid: The kernel internal quota identifier.
 28 * @dev: The device on which the fs is mounted (sb->s_dev)
 29 * @warntype: The type of the warning: QUOTA_NL_...
 30 *
 31 * This can be used by filesystems (including those which don't use
 32 * dquot) to send a message to userspace relating to quota limits.
 33 *
 34 */
 35
 36void quota_send_warning(struct kqid qid, dev_t dev,
 37			const char warntype)
 38{
 39	static atomic_t seq;
 40	struct sk_buff *skb;
 41	void *msg_head;
 42	int ret;
 43	int msg_size = 4 * nla_total_size(sizeof(u32)) +
 44		       2 * nla_total_size_64bit(sizeof(u64));
 45
 46	/* We have to allocate using GFP_NOFS as we are called from a
 47	 * filesystem performing write and thus further recursion into
 48	 * the fs to free some data could cause deadlocks. */
 49	skb = genlmsg_new(msg_size, GFP_NOFS);
 50	if (!skb) {
 51		printk(KERN_ERR
 52		  "VFS: Not enough memory to send quota warning.\n");
 53		return;
 54	}
 55	msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
 56			&quota_genl_family, 0, QUOTA_NL_C_WARNING);
 57	if (!msg_head) {
 58		printk(KERN_ERR
 59		  "VFS: Cannot store netlink header in quota warning.\n");
 60		goto err_out;
 61	}
 62	ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, qid.type);
 63	if (ret)
 64		goto attr_err_out;
 65	ret = nla_put_u64_64bit(skb, QUOTA_NL_A_EXCESS_ID,
 66				from_kqid_munged(&init_user_ns, qid),
 67				QUOTA_NL_A_PAD);
 68	if (ret)
 69		goto attr_err_out;
 70	ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
 71	if (ret)
 72		goto attr_err_out;
 73	ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR, MAJOR(dev));
 74	if (ret)
 75		goto attr_err_out;
 76	ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
 77	if (ret)
 78		goto attr_err_out;
 79	ret = nla_put_u64_64bit(skb, QUOTA_NL_A_CAUSED_ID,
 80				from_kuid_munged(&init_user_ns, current_uid()),
 81				QUOTA_NL_A_PAD);
 82	if (ret)
 83		goto attr_err_out;
 84	genlmsg_end(skb, msg_head);
 85
 86	genlmsg_multicast(&quota_genl_family, skb, 0, 0, GFP_NOFS);
 87	return;
 88attr_err_out:
 89	printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
 90err_out:
 91	kfree_skb(skb);
 92}
 93EXPORT_SYMBOL(quota_send_warning);
 94
 95static int __init quota_init(void)
 96{
 97	if (genl_register_family(&quota_genl_family) != 0)
 98		printk(KERN_ERR
 99		       "VFS: Failed to create quota netlink interface.\n");
100	return 0;
101};
102fs_initcall(quota_init);
v4.6
  1#include <linux/cred.h>
  2#include <linux/init.h>
  3#include <linux/kernel.h>
  4#include <linux/quotaops.h>
  5#include <linux/sched.h>
  6#include <linux/slab.h>
  7#include <net/netlink.h>
  8#include <net/genetlink.h>
  9
 10static const struct genl_multicast_group quota_mcgrps[] = {
 11	{ .name = "events", },
 12};
 13
 14/* Netlink family structure for quota */
 15static struct genl_family quota_genl_family = {
 16	/*
 17	 * Needed due to multicast group ID abuse - old code assumed
 18	 * the family ID was also a valid multicast group ID (which
 19	 * isn't true) and userspace might thus rely on it. Assign a
 20	 * static ID for this group to make dealing with that easier.
 21	 */
 22	.id = GENL_ID_VFS_DQUOT,
 23	.hdrsize = 0,
 24	.name = "VFS_DQUOT",
 25	.version = 1,
 26	.maxattr = QUOTA_NL_A_MAX,
 27	.mcgrps = quota_mcgrps,
 28	.n_mcgrps = ARRAY_SIZE(quota_mcgrps),
 29};
 30
 31/**
 32 * quota_send_warning - Send warning to userspace about exceeded quota
 33 * @qid: The kernel internal quota identifier.
 34 * @dev: The device on which the fs is mounted (sb->s_dev)
 35 * @warntype: The type of the warning: QUOTA_NL_...
 36 *
 37 * This can be used by filesystems (including those which don't use
 38 * dquot) to send a message to userspace relating to quota limits.
 39 *
 40 */
 41
 42void quota_send_warning(struct kqid qid, dev_t dev,
 43			const char warntype)
 44{
 45	static atomic_t seq;
 46	struct sk_buff *skb;
 47	void *msg_head;
 48	int ret;
 49	int msg_size = 4 * nla_total_size(sizeof(u32)) +
 50		       2 * nla_total_size(sizeof(u64));
 51
 52	/* We have to allocate using GFP_NOFS as we are called from a
 53	 * filesystem performing write and thus further recursion into
 54	 * the fs to free some data could cause deadlocks. */
 55	skb = genlmsg_new(msg_size, GFP_NOFS);
 56	if (!skb) {
 57		printk(KERN_ERR
 58		  "VFS: Not enough memory to send quota warning.\n");
 59		return;
 60	}
 61	msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
 62			&quota_genl_family, 0, QUOTA_NL_C_WARNING);
 63	if (!msg_head) {
 64		printk(KERN_ERR
 65		  "VFS: Cannot store netlink header in quota warning.\n");
 66		goto err_out;
 67	}
 68	ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, qid.type);
 69	if (ret)
 70		goto attr_err_out;
 71	ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID,
 72			  from_kqid_munged(&init_user_ns, qid));
 
 73	if (ret)
 74		goto attr_err_out;
 75	ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
 76	if (ret)
 77		goto attr_err_out;
 78	ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR, MAJOR(dev));
 79	if (ret)
 80		goto attr_err_out;
 81	ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
 82	if (ret)
 83		goto attr_err_out;
 84	ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID,
 85			  from_kuid_munged(&init_user_ns, current_uid()));
 
 86	if (ret)
 87		goto attr_err_out;
 88	genlmsg_end(skb, msg_head);
 89
 90	genlmsg_multicast(&quota_genl_family, skb, 0, 0, GFP_NOFS);
 91	return;
 92attr_err_out:
 93	printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
 94err_out:
 95	kfree_skb(skb);
 96}
 97EXPORT_SYMBOL(quota_send_warning);
 98
 99static int __init quota_init(void)
100{
101	if (genl_register_family(&quota_genl_family) != 0)
102		printk(KERN_ERR
103		       "VFS: Failed to create quota netlink interface.\n");
104	return 0;
105};
106fs_initcall(quota_init);