Lines Matching +full:tf +full:- +full:a

1 // SPDX-License-Identifier: GPL-2.0
7 * See Documentation/core-api/watch_queue.rst
37 * This must be called under the RCU read-lock, which makes
44 spin_lock_bh(&wqueue->lock); in lock_wqueue()
45 if (unlikely(!wqueue->pipe)) { in lock_wqueue()
46 spin_unlock_bh(&wqueue->lock); in lock_wqueue()
54 spin_unlock_bh(&wqueue->lock); in unlock_wqueue()
60 struct watch_queue *wqueue = (struct watch_queue *)buf->private; in watch_queue_pipe_buf_release()
68 bit = buf->offset + buf->len; in watch_queue_pipe_buf_release()
69 if ((bit & (WATCH_QUEUE_NOTE_SIZE - 1)) == 0) in watch_queue_pipe_buf_release()
70 bit -= WATCH_QUEUE_NOTE_SIZE; in watch_queue_pipe_buf_release()
73 page = buf->page; in watch_queue_pipe_buf_release()
74 bit += page->private; in watch_queue_pipe_buf_release()
76 set_bit(bit, wqueue->notes_bitmap); in watch_queue_pipe_buf_release()
83 /* New data written to a pipe may be appended to a buffer with this type. */
91 * Post a notification to a watch queue.
101 struct pipe_inode_info *pipe = wqueue->pipe; in post_one_notification()
107 spin_lock_irq(&pipe->rd_wait.lock); in post_one_notification()
109 head = pipe->head; in post_one_notification()
110 tail = pipe->tail; in post_one_notification()
111 if (pipe_full(head, tail, pipe->ring_size)) in post_one_notification()
114 note = find_first_bit(wqueue->notes_bitmap, wqueue->nr_notes); in post_one_notification()
115 if (note >= wqueue->nr_notes) in post_one_notification()
118 page = wqueue->notes[note / WATCH_QUEUE_NOTES_PER_PAGE]; in post_one_notification()
121 len = n->info & WATCH_INFO_LENGTH; in post_one_notification()
127 buf->page = page; in post_one_notification()
128 buf->private = (unsigned long)wqueue; in post_one_notification()
129 buf->ops = &watch_queue_pipe_buf_ops; in post_one_notification()
130 buf->offset = offset; in post_one_notification()
131 buf->len = len; in post_one_notification()
132 buf->flags = PIPE_BUF_FLAG_WHOLE; in post_one_notification()
133 smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */ in post_one_notification()
135 if (!test_and_clear_bit(note, wqueue->notes_bitmap)) { in post_one_notification()
136 spin_unlock_irq(&pipe->rd_wait.lock); in post_one_notification()
139 wake_up_interruptible_sync_poll_locked(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM); in post_one_notification()
143 spin_unlock_irq(&pipe->rd_wait.lock); in post_one_notification()
145 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); in post_one_notification()
149 buf = pipe_buf(pipe, head - 1); in post_one_notification()
150 buf->flags |= PIPE_BUF_FLAG_LOSS; in post_one_notification()
155 * Apply filter rules to a notification.
161 unsigned int st_bits = sizeof(wt->subtype_filter[0]) * 8; in filter_watch_notification()
162 unsigned int st_index = n->subtype / st_bits; in filter_watch_notification()
163 unsigned int st_bit = 1U << (n->subtype % st_bits); in filter_watch_notification()
166 if (!test_bit(n->type, wf->type_filter)) in filter_watch_notification()
169 for (i = 0; i < wf->nr_filters; i++) { in filter_watch_notification()
170 wt = &wf->filters[i]; in filter_watch_notification()
171 if (n->type == wt->type && in filter_watch_notification()
172 (wt->subtype_filter[st_index] & st_bit) && in filter_watch_notification()
173 (n->info & wt->info_mask) == wt->info_filter) in filter_watch_notification()
177 return false; /* If there is a filter, the default is to reject. */ in filter_watch_notification()
181 * __post_watch_notification - Post an event notification
187 * Post a notification of an event into a set of watch queues and let the users
190 * The size of the notification should be set in n->info & WATCH_INFO_LENGTH and
202 if (((n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT) == 0) { in __post_watch_notification()
209 hlist_for_each_entry_rcu(watch, &wlist->watchers, list_node) { in __post_watch_notification()
210 if (watch->id != id) in __post_watch_notification()
212 n->info &= ~WATCH_INFO_ID; in __post_watch_notification()
213 n->info |= watch->info_id; in __post_watch_notification()
215 wqueue = rcu_dereference(watch->queue); in __post_watch_notification()
216 wf = rcu_dereference(wqueue->filter); in __post_watch_notification()
220 if (security_post_notification(watch->cred, cred, n) < 0) in __post_watch_notification()
239 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_size()
246 return -ENODEV; in watch_queue_set_size()
247 if (wqueue->notes) in watch_queue_set_size()
248 return -EBUSY; in watch_queue_set_size()
251 nr_notes > 512) /* TODO: choose a better hard limit */ in watch_queue_set_size()
252 return -EINVAL; in watch_queue_set_size()
254 nr_pages = (nr_notes + WATCH_QUEUE_NOTES_PER_PAGE - 1); in watch_queue_set_size()
256 user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_pages); in watch_queue_set_size()
258 if (nr_pages > pipe->max_usage && in watch_queue_set_size()
262 ret = -EPERM; in watch_queue_set_size()
277 pipe->max_usage = nr_pages; in watch_queue_set_size()
278 pipe->nr_accounted = nr_pages; in watch_queue_set_size()
280 ret = -ENOMEM; in watch_queue_set_size()
289 pages[i]->private = i * WATCH_QUEUE_NOTES_PER_PAGE; in watch_queue_set_size()
297 wqueue->notes = pages; in watch_queue_set_size()
298 wqueue->notes_bitmap = bitmap; in watch_queue_set_size()
299 wqueue->nr_pages = nr_pages; in watch_queue_set_size()
300 wqueue->nr_notes = nr_notes; in watch_queue_set_size()
304 while (--i >= 0) in watch_queue_set_size()
308 (void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted); in watch_queue_set_size()
313 * Set the filter on a watch queue.
318 struct watch_notification_type_filter *tf; in watch_queue_set_filter() local
322 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_filter()
326 return -ENODEV; in watch_queue_set_filter()
336 return -EFAULT; in watch_queue_set_filter()
340 return -EINVAL; in watch_queue_set_filter()
342 tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); in watch_queue_set_filter()
343 if (IS_ERR(tf)) in watch_queue_set_filter()
344 return PTR_ERR(tf); in watch_queue_set_filter()
346 ret = -EINVAL; in watch_queue_set_filter()
348 if ((tf[i].info_filter & ~tf[i].info_mask) || in watch_queue_set_filter()
349 tf[i].info_mask & WATCH_INFO_LENGTH) in watch_queue_set_filter()
352 if (tf[i].type >= WATCH_TYPE__NR) in watch_queue_set_filter()
358 * user-specified filters. in watch_queue_set_filter()
360 ret = -ENOMEM; in watch_queue_set_filter()
364 wfilter->nr_filters = nr_filter; in watch_queue_set_filter()
366 q = wfilter->filters; in watch_queue_set_filter()
368 if (tf[i].type >= WATCH_TYPE__NR) in watch_queue_set_filter()
371 q->type = tf[i].type; in watch_queue_set_filter()
372 q->info_filter = tf[i].info_filter; in watch_queue_set_filter()
373 q->info_mask = tf[i].info_mask; in watch_queue_set_filter()
374 q->subtype_filter[0] = tf[i].subtype_filter[0]; in watch_queue_set_filter()
375 __set_bit(q->type, wfilter->type_filter); in watch_queue_set_filter()
379 kfree(tf); in watch_queue_set_filter()
382 wfilter = rcu_replace_pointer(wqueue->filter, wfilter, in watch_queue_set_filter()
383 lockdep_is_held(&pipe->mutex)); in watch_queue_set_filter()
390 kfree(tf); in watch_queue_set_filter()
401 for (i = 0; i < wqueue->nr_pages; i++) in __put_watch_queue()
402 __free_page(wqueue->notes[i]); in __put_watch_queue()
403 kfree(wqueue->notes); in __put_watch_queue()
404 bitmap_free(wqueue->notes_bitmap); in __put_watch_queue()
406 wfilter = rcu_access_pointer(wqueue->filter); in __put_watch_queue()
413 * put_watch_queue - Dispose of a ref on a watchqueue.
418 kref_put(&wqueue->usage, __put_watch_queue); in put_watch_queue()
426 put_watch_queue(rcu_access_pointer(watch->queue)); in free_watch()
427 atomic_dec(&watch->cred->user->nr_watches); in free_watch()
428 put_cred(watch->cred); in free_watch()
436 call_rcu(&watch->rcu, free_watch); in __put_watch()
440 * Discard a watch.
444 kref_put(&watch->usage, __put_watch); in put_watch()
448 * init_watch - Initialise a watch
452 * Initialise a watch and set the watch queue.
456 kref_init(&watch->usage); in init_watch()
457 INIT_HLIST_NODE(&watch->list_node); in init_watch()
458 INIT_HLIST_NODE(&watch->queue_node); in init_watch()
459 rcu_assign_pointer(watch->queue, wqueue); in init_watch()
467 hlist_for_each_entry(w, &wlist->watchers, list_node) { in add_one_watch()
468 struct watch_queue *wq = rcu_access_pointer(w->queue); in add_one_watch()
469 if (wqueue == wq && watch->id == w->id) in add_one_watch()
470 return -EBUSY; in add_one_watch()
474 if (atomic_inc_return(&cred->user->nr_watches) > task_rlimit(current, RLIMIT_NOFILE)) { in add_one_watch()
475 atomic_dec(&cred->user->nr_watches); in add_one_watch()
476 return -EAGAIN; in add_one_watch()
479 watch->cred = get_cred(cred); in add_one_watch()
480 rcu_assign_pointer(watch->watch_list, wlist); in add_one_watch()
482 kref_get(&wqueue->usage); in add_one_watch()
483 kref_get(&watch->usage); in add_one_watch()
484 hlist_add_head(&watch->queue_node, &wqueue->watches); in add_one_watch()
485 hlist_add_head_rcu(&watch->list_node, &wlist->watchers); in add_one_watch()
490 * add_watch_to_object - Add a watch on an object to a watch list
494 * @watch->queue must have been set to point to the queue to post notifications
495 * to and the watch list of the object to be watched. @watch->cred must also
496 * have been set to the appropriate credentials and a ref taken on them.
504 int ret = -ENOENT; in add_watch_to_object()
508 wqueue = rcu_access_pointer(watch->queue); in add_watch_to_object()
510 spin_lock(&wlist->lock); in add_watch_to_object()
512 spin_unlock(&wlist->lock); in add_watch_to_object()
522 * remove_watch_from_object - Remove a watch or all watches from an object.
528 * Remove a specific watch or all watches from an object. A notification is
537 int ret = -EBADSLT; in remove_watch_from_object()
542 spin_lock(&wlist->lock); in remove_watch_from_object()
543 hlist_for_each_entry(watch, &wlist->watchers, list_node) { in remove_watch_from_object()
545 (watch->id == id && rcu_access_pointer(watch->queue) == wq)) in remove_watch_from_object()
548 spin_unlock(&wlist->lock); in remove_watch_from_object()
553 hlist_del_init_rcu(&watch->list_node); in remove_watch_from_object()
554 rcu_assign_pointer(watch->watch_list, NULL); in remove_watch_from_object()
555 spin_unlock(&wlist->lock); in remove_watch_from_object()
561 n.watch.info = watch->info_id | watch_sizeof(n.watch); in remove_watch_from_object()
564 n.watch.info = watch->info_id | watch_sizeof(n); in remove_watch_from_object()
566 wqueue = rcu_dereference(watch->queue); in remove_watch_from_object()
571 if (!hlist_unhashed(&watch->queue_node)) { in remove_watch_from_object()
572 hlist_del_init_rcu(&watch->queue_node); in remove_watch_from_object()
579 if (wlist->release_watch) { in remove_watch_from_object()
582 release_watch = wlist->release_watch; in remove_watch_from_object()
589 if (all && !hlist_empty(&wlist->watchers)) in remove_watch_from_object()
598 * Remove all the watches that are contributory to a queue. This has the
609 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
615 wqueue->pipe = NULL; in watch_queue_clear()
617 while (!hlist_empty(&wqueue->watches)) { in watch_queue_clear()
618 watch = hlist_entry(wqueue->watches.first, struct watch, queue_node); in watch_queue_clear()
619 hlist_del_init_rcu(&watch->queue_node); in watch_queue_clear()
620 /* We now own a ref on the watch. */ in watch_queue_clear()
621 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
624 * get the list lock - which would cause a deadlock if someone in watch_queue_clear()
626 * posting a notification. in watch_queue_clear()
628 wlist = rcu_dereference(watch->watch_list); in watch_queue_clear()
632 spin_lock(&wlist->lock); in watch_queue_clear()
634 release = !hlist_unhashed(&watch->list_node); in watch_queue_clear()
636 hlist_del_init_rcu(&watch->list_node); in watch_queue_clear()
637 rcu_assign_pointer(watch->watch_list, NULL); in watch_queue_clear()
639 /* We now own a second ref on the watch. */ in watch_queue_clear()
642 release_watch = wlist->release_watch; in watch_queue_clear()
643 spin_unlock(&wlist->lock); in watch_queue_clear()
659 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
662 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
667 * get_watch_queue - Get a watch queue from its file descriptor.
673 struct watch_queue *wqueue = ERR_PTR(-EINVAL); in get_watch_queue()
678 if (pipe && pipe->watch_queue) { in get_watch_queue()
679 wqueue = pipe->watch_queue; in get_watch_queue()
680 kref_get(&wqueue->usage); in get_watch_queue()
689 * Initialise a watch queue
697 return -ENOMEM; in watch_queue_init()
699 wqueue->pipe = pipe; in watch_queue_init()
700 kref_init(&wqueue->usage); in watch_queue_init()
701 spin_lock_init(&wqueue->lock); in watch_queue_init()
702 INIT_HLIST_HEAD(&wqueue->watches); in watch_queue_init()
704 pipe->watch_queue = wqueue; in watch_queue_init()