linux/include/linux/watch_queue.h
<<
>>
Prefs
   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
  19struct cred;
  20
  21struct 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
  28struct 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
  37struct 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 */
  54struct 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 */
  72struct watch_list {
  73        struct rcu_head         rcu;
  74        struct hlist_head       watchers;
  75        void (*release_watch)(struct watch *);
  76        spinlock_t              lock;
  77};
  78
  79extern void __post_watch_notification(struct watch_list *,
  80                                      struct watch_notification *,
  81                                      const struct cred *,
  82                                      u64);
  83extern struct watch_queue *get_watch_queue(int);
  84extern void put_watch_queue(struct watch_queue *);
  85extern void init_watch(struct watch *, struct watch_queue *);
  86extern int add_watch_to_object(struct watch *, struct watch_list *);
  87extern int remove_watch_from_object(struct watch_list *, struct watch_queue *, u64, bool);
  88extern long watch_queue_set_size(struct pipe_inode_info *, unsigned int);
  89extern long watch_queue_set_filter(struct pipe_inode_info *,
  90                                   struct watch_notification_filter __user *);
  91extern int watch_queue_init(struct pipe_inode_info *);
  92extern void watch_queue_clear(struct watch_queue *);
  93
  94static 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
 102static 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
 111static 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
 126static inline int watch_queue_init(struct pipe_inode_info *pipe)
 127{
 128        return -ENOPKG;
 129}
 130
 131#endif
 132
 133#endif /* _LINUX_WATCH_QUEUE_H */
 134