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 */