Linux Audio

Check our new training course

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