Lines Matching +full:tf +full:- +full:a
1 // SPDX-License-Identifier: GPL-2.0
40 struct watch_queue *wqueue = (struct watch_queue *)buf->private; in watch_queue_pipe_buf_release()
48 bit = buf->offset + buf->len; in watch_queue_pipe_buf_release()
49 if ((bit & (WATCH_QUEUE_NOTE_SIZE - 1)) == 0) in watch_queue_pipe_buf_release()
50 bit -= WATCH_QUEUE_NOTE_SIZE; in watch_queue_pipe_buf_release()
53 page = buf->page; in watch_queue_pipe_buf_release()
54 bit += page->index; in watch_queue_pipe_buf_release()
56 set_bit(bit, wqueue->notes_bitmap); in watch_queue_pipe_buf_release()
62 /* New data written to a pipe may be appended to a buffer with this type. */
70 * Post a notification to a watch queue.
76 struct pipe_inode_info *pipe = wqueue->pipe; in post_one_notification()
85 spin_lock_irq(&pipe->rd_wait.lock); in post_one_notification()
87 if (wqueue->defunct) in post_one_notification()
90 mask = pipe->ring_size - 1; in post_one_notification()
91 head = pipe->head; in post_one_notification()
92 tail = pipe->tail; in post_one_notification()
93 if (pipe_full(head, tail, pipe->ring_size)) in post_one_notification()
96 note = find_first_bit(wqueue->notes_bitmap, wqueue->nr_notes); in post_one_notification()
97 if (note >= wqueue->nr_notes) in post_one_notification()
100 page = wqueue->notes[note / WATCH_QUEUE_NOTES_PER_PAGE]; in post_one_notification()
103 len = n->info & WATCH_INFO_LENGTH; in post_one_notification()
108 buf = &pipe->bufs[head & mask]; in post_one_notification()
109 buf->page = page; in post_one_notification()
110 buf->private = (unsigned long)wqueue; in post_one_notification()
111 buf->ops = &watch_queue_pipe_buf_ops; in post_one_notification()
112 buf->offset = offset; in post_one_notification()
113 buf->len = len; in post_one_notification()
114 buf->flags = PIPE_BUF_FLAG_WHOLE; in post_one_notification()
115 pipe->head = head + 1; in post_one_notification()
117 if (!test_and_clear_bit(note, wqueue->notes_bitmap)) { in post_one_notification()
118 spin_unlock_irq(&pipe->rd_wait.lock); in post_one_notification()
121 wake_up_interruptible_sync_poll_locked(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM); in post_one_notification()
125 spin_unlock_irq(&pipe->rd_wait.lock); in post_one_notification()
127 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); in post_one_notification()
131 buf = &pipe->bufs[(head - 1) & mask]; in post_one_notification()
132 buf->flags |= PIPE_BUF_FLAG_LOSS; in post_one_notification()
137 * Apply filter rules to a notification.
143 unsigned int st_bits = sizeof(wt->subtype_filter[0]) * 8; in filter_watch_notification()
144 unsigned int st_index = n->subtype / st_bits; in filter_watch_notification()
145 unsigned int st_bit = 1U << (n->subtype % st_bits); in filter_watch_notification()
148 if (!test_bit(n->type, wf->type_filter)) in filter_watch_notification()
151 for (i = 0; i < wf->nr_filters; i++) { in filter_watch_notification()
152 wt = &wf->filters[i]; in filter_watch_notification()
153 if (n->type == wt->type && in filter_watch_notification()
154 (wt->subtype_filter[st_index] & st_bit) && in filter_watch_notification()
155 (n->info & wt->info_mask) == wt->info_filter) in filter_watch_notification()
159 return false; /* If there is a filter, the default is to reject. */ in filter_watch_notification()
163 * __post_watch_notification - Post an event notification
169 * Post a notification of an event into a set of watch queues and let the users
172 * The size of the notification should be set in n->info & WATCH_INFO_LENGTH and
184 if (((n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT) == 0) { in __post_watch_notification()
191 hlist_for_each_entry_rcu(watch, &wlist->watchers, list_node) { in __post_watch_notification()
192 if (watch->id != id) in __post_watch_notification()
194 n->info &= ~WATCH_INFO_ID; in __post_watch_notification()
195 n->info |= watch->info_id; in __post_watch_notification()
197 wqueue = rcu_dereference(watch->queue); in __post_watch_notification()
198 wf = rcu_dereference(wqueue->filter); in __post_watch_notification()
202 if (security_post_notification(watch->cred, cred, n) < 0) in __post_watch_notification()
218 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_size()
226 return -ENODEV; in watch_queue_set_size()
227 if (wqueue->notes) in watch_queue_set_size()
228 return -EBUSY; in watch_queue_set_size()
231 nr_notes > 512) /* TODO: choose a better hard limit */ in watch_queue_set_size()
232 return -EINVAL; in watch_queue_set_size()
234 nr_pages = (nr_notes + WATCH_QUEUE_NOTES_PER_PAGE - 1); in watch_queue_set_size()
236 user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_pages); in watch_queue_set_size()
238 if (nr_pages > pipe->max_usage && in watch_queue_set_size()
242 ret = -EPERM; in watch_queue_set_size()
258 pages[i]->index = i * WATCH_QUEUE_NOTES_PER_PAGE; in watch_queue_set_size()
261 bmsize = (nr_notes + BITS_PER_LONG - 1) / BITS_PER_LONG; in watch_queue_set_size()
268 wqueue->notes = pages; in watch_queue_set_size()
269 wqueue->notes_bitmap = bitmap; in watch_queue_set_size()
270 wqueue->nr_pages = nr_pages; in watch_queue_set_size()
271 wqueue->nr_notes = nr_pages * WATCH_QUEUE_NOTES_PER_PAGE; in watch_queue_set_size()
279 (void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted); in watch_queue_set_size()
284 * Set the filter on a watch queue.
289 struct watch_notification_type_filter *tf; in watch_queue_set_filter() local
293 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_filter()
297 return -ENODEV; in watch_queue_set_filter()
307 return -EFAULT; in watch_queue_set_filter()
311 return -EINVAL; in watch_queue_set_filter()
313 tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf)); in watch_queue_set_filter()
314 if (IS_ERR(tf)) in watch_queue_set_filter()
315 return PTR_ERR(tf); in watch_queue_set_filter()
317 ret = -EINVAL; in watch_queue_set_filter()
319 if ((tf[i].info_filter & ~tf[i].info_mask) || in watch_queue_set_filter()
320 tf[i].info_mask & WATCH_INFO_LENGTH) in watch_queue_set_filter()
323 if (tf[i].type >= sizeof(wfilter->type_filter) * 8) in watch_queue_set_filter()
329 * user-specified filters. in watch_queue_set_filter()
331 ret = -ENOMEM; in watch_queue_set_filter()
335 wfilter->nr_filters = nr_filter; in watch_queue_set_filter()
337 q = wfilter->filters; in watch_queue_set_filter()
339 if (tf[i].type >= sizeof(wfilter->type_filter) * BITS_PER_LONG) in watch_queue_set_filter()
342 q->type = tf[i].type; in watch_queue_set_filter()
343 q->info_filter = tf[i].info_filter; in watch_queue_set_filter()
344 q->info_mask = tf[i].info_mask; in watch_queue_set_filter()
345 q->subtype_filter[0] = tf[i].subtype_filter[0]; in watch_queue_set_filter()
346 __set_bit(q->type, wfilter->type_filter); in watch_queue_set_filter()
350 kfree(tf); in watch_queue_set_filter()
353 wfilter = rcu_replace_pointer(wqueue->filter, wfilter, in watch_queue_set_filter()
354 lockdep_is_held(&pipe->mutex)); in watch_queue_set_filter()
361 kfree(tf); in watch_queue_set_filter()
372 for (i = 0; i < wqueue->nr_pages; i++) in __put_watch_queue()
373 __free_page(wqueue->notes[i]); in __put_watch_queue()
375 wfilter = rcu_access_pointer(wqueue->filter); in __put_watch_queue()
382 * put_watch_queue - Dispose of a ref on a watchqueue.
387 kref_put(&wqueue->usage, __put_watch_queue); in put_watch_queue()
395 put_watch_queue(rcu_access_pointer(watch->queue)); in free_watch()
396 atomic_dec(&watch->cred->user->nr_watches); in free_watch()
397 put_cred(watch->cred); in free_watch()
404 call_rcu(&watch->rcu, free_watch); in __put_watch()
408 * Discard a watch.
412 kref_put(&watch->usage, __put_watch); in put_watch()
416 * init_watch - Initialise a watch
420 * Initialise a watch and set the watch queue.
424 kref_init(&watch->usage); in init_watch()
425 INIT_HLIST_NODE(&watch->list_node); in init_watch()
426 INIT_HLIST_NODE(&watch->queue_node); in init_watch()
427 rcu_assign_pointer(watch->queue, wqueue); in init_watch()
431 * add_watch_to_object - Add a watch on an object to a watch list
435 * @watch->queue must have been set to point to the queue to post notifications
436 * to and the watch list of the object to be watched. @watch->cred must also
437 * have been set to the appropriate credentials and a ref taken on them.
444 struct watch_queue *wqueue = rcu_access_pointer(watch->queue); in add_watch_to_object()
447 hlist_for_each_entry(w, &wlist->watchers, list_node) { in add_watch_to_object()
448 struct watch_queue *wq = rcu_access_pointer(w->queue); in add_watch_to_object()
449 if (wqueue == wq && watch->id == w->id) in add_watch_to_object()
450 return -EBUSY; in add_watch_to_object()
453 watch->cred = get_current_cred(); in add_watch_to_object()
454 rcu_assign_pointer(watch->watch_list, wlist); in add_watch_to_object()
456 if (atomic_inc_return(&watch->cred->user->nr_watches) > in add_watch_to_object()
458 atomic_dec(&watch->cred->user->nr_watches); in add_watch_to_object()
459 put_cred(watch->cred); in add_watch_to_object()
460 return -EAGAIN; in add_watch_to_object()
463 spin_lock_bh(&wqueue->lock); in add_watch_to_object()
464 kref_get(&wqueue->usage); in add_watch_to_object()
465 kref_get(&watch->usage); in add_watch_to_object()
466 hlist_add_head(&watch->queue_node, &wqueue->watches); in add_watch_to_object()
467 spin_unlock_bh(&wqueue->lock); in add_watch_to_object()
469 hlist_add_head(&watch->list_node, &wlist->watchers); in add_watch_to_object()
475 * remove_watch_from_object - Remove a watch or all watches from an object.
481 * Remove a specific watch or all watches from an object. A notification is
490 int ret = -EBADSLT; in remove_watch_from_object()
495 spin_lock(&wlist->lock); in remove_watch_from_object()
496 hlist_for_each_entry(watch, &wlist->watchers, list_node) { in remove_watch_from_object()
498 (watch->id == id && rcu_access_pointer(watch->queue) == wq)) in remove_watch_from_object()
501 spin_unlock(&wlist->lock); in remove_watch_from_object()
506 hlist_del_init_rcu(&watch->list_node); in remove_watch_from_object()
507 rcu_assign_pointer(watch->watch_list, NULL); in remove_watch_from_object()
508 spin_unlock(&wlist->lock); in remove_watch_from_object()
514 n.watch.info = watch->info_id | watch_sizeof(n.watch); in remove_watch_from_object()
517 n.watch.info = watch->info_id | watch_sizeof(n); in remove_watch_from_object()
519 wqueue = rcu_dereference(watch->queue); in remove_watch_from_object()
527 spin_lock_bh(&wqueue->lock); in remove_watch_from_object()
529 if (!hlist_unhashed(&watch->queue_node)) { in remove_watch_from_object()
530 hlist_del_init_rcu(&watch->queue_node); in remove_watch_from_object()
534 spin_unlock_bh(&wqueue->lock); in remove_watch_from_object()
537 if (wlist->release_watch) { in remove_watch_from_object()
540 release_watch = wlist->release_watch; in remove_watch_from_object()
547 if (all && !hlist_empty(&wlist->watchers)) in remove_watch_from_object()
556 * Remove all the watches that are contributory to a queue. This has the
567 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
570 wqueue->defunct = true; in watch_queue_clear()
572 while (!hlist_empty(&wqueue->watches)) { in watch_queue_clear()
573 watch = hlist_entry(wqueue->watches.first, struct watch, queue_node); in watch_queue_clear()
574 hlist_del_init_rcu(&watch->queue_node); in watch_queue_clear()
575 /* We now own a ref on the watch. */ in watch_queue_clear()
576 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
579 * get the list lock - which would cause a deadlock if someone in watch_queue_clear()
581 * posting a notification. in watch_queue_clear()
583 wlist = rcu_dereference(watch->watch_list); in watch_queue_clear()
587 spin_lock(&wlist->lock); in watch_queue_clear()
589 release = !hlist_unhashed(&watch->list_node); in watch_queue_clear()
591 hlist_del_init_rcu(&watch->list_node); in watch_queue_clear()
592 rcu_assign_pointer(watch->watch_list, NULL); in watch_queue_clear()
594 /* We now own a second ref on the watch. */ in watch_queue_clear()
597 release_watch = wlist->release_watch; in watch_queue_clear()
598 spin_unlock(&wlist->lock); in watch_queue_clear()
614 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
617 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
622 * get_watch_queue - Get a watch queue from its file descriptor.
628 struct watch_queue *wqueue = ERR_PTR(-EINVAL); in get_watch_queue()
634 if (pipe && pipe->watch_queue) { in get_watch_queue()
635 wqueue = pipe->watch_queue; in get_watch_queue()
636 kref_get(&wqueue->usage); in get_watch_queue()
646 * Initialise a watch queue
654 return -ENOMEM; in watch_queue_init()
656 wqueue->pipe = pipe; in watch_queue_init()
657 kref_init(&wqueue->usage); in watch_queue_init()
658 spin_lock_init(&wqueue->lock); in watch_queue_init()
659 INIT_HLIST_HEAD(&wqueue->watches); in watch_queue_init()
661 pipe->watch_queue = wqueue; in watch_queue_init()