LCOV - code coverage report
Current view: top level - fs/quota - netlink.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 3 44 6.8 %
Date: 2022-04-01 13:59:58 Functions: 1 2 50.0 %
Branches: 1 20 5.0 %

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

Generated by: LCOV version 1.14