LCOV - code coverage report
Current view: top level - include/linux - watch_queue.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 2 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /* User-mappable watch queue
       3             :  *
       4             :  * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
       5             :  * Written by David Howells (dhowells@redhat.com)
       6             :  *
       7             :  * See Documentation/watch_queue.rst
       8             :  */
       9             : 
      10             : #ifndef _LINUX_WATCH_QUEUE_H
      11             : #define _LINUX_WATCH_QUEUE_H
      12             : 
      13             : #include <uapi/linux/watch_queue.h>
      14             : #include <linux/kref.h>
      15             : #include <linux/rcupdate.h>
      16             : 
      17             : #ifdef CONFIG_WATCH_QUEUE
      18             : 
      19             : struct cred;
      20             : 
      21             : struct watch_type_filter {
      22             :         enum watch_notification_type type;
      23             :         __u32           subtype_filter[1];      /* Bitmask of subtypes to filter on */
      24             :         __u32           info_filter;            /* Filter on watch_notification::info */
      25             :         __u32           info_mask;              /* Mask of relevant bits in info_filter */
      26             : };
      27             : 
      28             : struct watch_filter {
      29             :         union {
      30             :                 struct rcu_head rcu;
      31             :                 unsigned long   type_filter[2]; /* Bitmask of accepted types */
      32             :         };
      33             :         u32                     nr_filters;     /* Number of filters */
      34             :         struct watch_type_filter filters[];
      35             : };
      36             : 
      37             : struct watch_queue {
      38             :         struct rcu_head         rcu;
      39             :         struct watch_filter __rcu *filter;
      40             :         struct pipe_inode_info  *pipe;          /* The pipe we're using as a buffer */
      41             :         struct hlist_head       watches;        /* Contributory watches */
      42             :         struct page             **notes;        /* Preallocated notifications */
      43             :         unsigned long           *notes_bitmap;  /* Allocation bitmap for notes */
      44             :         struct kref             usage;          /* Object usage count */
      45             :         spinlock_t              lock;
      46             :         unsigned int            nr_notes;       /* Number of notes */
      47             :         unsigned int            nr_pages;       /* Number of pages in notes[] */
      48             :         bool                    defunct;        /* T when queues closed */
      49             : };
      50             : 
      51             : /*
      52             :  * Representation of a watch on an object.
      53             :  */
      54             : struct watch {
      55             :         union {
      56             :                 struct rcu_head rcu;
      57             :                 u32             info_id;        /* ID to be OR'd in to info field */
      58             :         };
      59             :         struct watch_queue __rcu *queue;        /* Queue to post events to */
      60             :         struct hlist_node       queue_node;     /* Link in queue->watches */
      61             :         struct watch_list __rcu *watch_list;
      62             :         struct hlist_node       list_node;      /* Link in watch_list->watchers */
      63             :         const struct cred       *cred;          /* Creds of the owner of the watch */
      64             :         void                    *private;       /* Private data for the watched object */
      65             :         u64                     id;             /* Internal identifier */
      66             :         struct kref             usage;          /* Object usage count */
      67             : };
      68             : 
      69             : /*
      70             :  * List of watches on an object.
      71             :  */
      72             : struct watch_list {
      73             :         struct rcu_head         rcu;
      74             :         struct hlist_head       watchers;
      75             :         void (*release_watch)(struct watch *);
      76             :         spinlock_t              lock;
      77             : };
      78             : 
      79             : extern void __post_watch_notification(struct watch_list *,
      80             :                                       struct watch_notification *,
      81             :                                       const struct cred *,
      82             :                                       u64);
      83             : extern struct watch_queue *get_watch_queue(int);
      84             : extern void put_watch_queue(struct watch_queue *);
      85             : extern void init_watch(struct watch *, struct watch_queue *);
      86             : extern int add_watch_to_object(struct watch *, struct watch_list *);
      87             : extern int remove_watch_from_object(struct watch_list *, struct watch_queue *, u64, bool);
      88             : extern long watch_queue_set_size(struct pipe_inode_info *, unsigned int);
      89             : extern long watch_queue_set_filter(struct pipe_inode_info *,
      90             :                                    struct watch_notification_filter __user *);
      91             : extern int watch_queue_init(struct pipe_inode_info *);
      92             : extern void watch_queue_clear(struct watch_queue *);
      93             : 
      94             : static inline void init_watch_list(struct watch_list *wlist,
      95             :                                    void (*release_watch)(struct watch *))
      96             : {
      97             :         INIT_HLIST_HEAD(&wlist->watchers);
      98             :         spin_lock_init(&wlist->lock);
      99             :         wlist->release_watch = release_watch;
     100             : }
     101             : 
     102             : static inline void post_watch_notification(struct watch_list *wlist,
     103             :                                            struct watch_notification *n,
     104             :                                            const struct cred *cred,
     105             :                                            u64 id)
     106             : {
     107             :         if (unlikely(wlist))
     108             :                 __post_watch_notification(wlist, n, cred, id);
     109             : }
     110             : 
     111             : static inline void remove_watch_list(struct watch_list *wlist, u64 id)
     112             : {
     113             :         if (wlist) {
     114             :                 remove_watch_from_object(wlist, NULL, id, true);
     115             :                 kfree_rcu(wlist, rcu);
     116             :         }
     117             : }
     118             : 
     119             : /**
     120             :  * watch_sizeof - Calculate the information part of the size of a watch record,
     121             :  * given the structure size.
     122             :  */
     123             : #define watch_sizeof(STRUCT) (sizeof(STRUCT) << WATCH_INFO_LENGTH__SHIFT)
     124             : 
     125             : #else
     126           0 : static inline int watch_queue_init(struct pipe_inode_info *pipe)
     127             : {
     128           0 :         return -ENOPKG;
     129             : }
     130             : 
     131             : #endif
     132             : 
     133             : #endif /* _LINUX_WATCH_QUEUE_H */

Generated by: LCOV version 1.14