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 mask = pipe->ring_size - 1; in post_one_notification()
110 head = pipe->head; in post_one_notification()
111 tail = pipe->tail; in post_one_notification()
112 if (pipe_full(head, tail, pipe->ring_size)) in post_one_notification()
115 note = find_first_bit(wqueue->notes_bitmap, wqueue->nr_notes); in post_one_notification()
116 if (note >= wqueue->nr_notes) in post_one_notification()
119 page = wqueue->notes[note / WATCH_QUEUE_NOTES_PER_PAGE]; in post_one_notification()
122 len = n->info & WATCH_INFO_LENGTH; in post_one_notification()
127 buf = &pipe->bufs[head & mask]; in post_one_notification()
128 buf->page = page; in post_one_notification()
129 buf->private = (unsigned long)wqueue; in post_one_notification()
130 buf->ops = &watch_queue_pipe_buf_ops; in post_one_notification()
131 buf->offset = offset; in post_one_notification()
132 buf->len = len; in post_one_notification()
133 buf->flags = PIPE_BUF_FLAG_WHOLE; in post_one_notification()
134 smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */ in post_one_notification()
136 if (!test_and_clear_bit(note, wqueue->notes_bitmap)) { in post_one_notification()
137 spin_unlock_irq(&pipe->rd_wait.lock); in post_one_notification()
140 wake_up_interruptible_sync_poll_locked(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM); in post_one_notification()
144 spin_unlock_irq(&pipe->rd_wait.lock); in post_one_notification()
146 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); in post_one_notification()
150 buf = &pipe->bufs[(head - 1) & mask]; in post_one_notification()
151 buf->flags |= PIPE_BUF_FLAG_LOSS; in post_one_notification()
156 * Apply filter rules to a notification.
162 unsigned int st_bits = sizeof(wt->subtype_filter[0]) * 8; in filter_watch_notification()
163 unsigned int st_index = n->subtype / st_bits; in filter_watch_notification()
164 unsigned int st_bit = 1U << (n->subtype % st_bits); in filter_watch_notification()
167 if (!test_bit(n->type, wf->type_filter)) in filter_watch_notification()
170 for (i = 0; i < wf->nr_filters; i++) { in filter_watch_notification()
171 wt = &wf->filters[i]; in filter_watch_notification()
172 if (n->type == wt->type && in filter_watch_notification()
173 (wt->subtype_filter[st_index] & st_bit) && in filter_watch_notification()
174 (n->info & wt->info_mask) == wt->info_filter) in filter_watch_notification()
178 return false; /* If there is a filter, the default is to reject. */ in filter_watch_notification()
182 * __post_watch_notification - Post an event notification
188 * Post a notification of an event into a set of watch queues and let the users
191 * The size of the notification should be set in n->info & WATCH_INFO_LENGTH and
203 if (((n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT) == 0) { in __post_watch_notification()
210 hlist_for_each_entry_rcu(watch, &wlist->watchers, list_node) { in __post_watch_notification()
211 if (watch->id != id) in __post_watch_notification()
213 n->info &= ~WATCH_INFO_ID; in __post_watch_notification()
214 n->info |= watch->info_id; in __post_watch_notification()
216 wqueue = rcu_dereference(watch->queue); in __post_watch_notification()
217 wf = rcu_dereference(wqueue->filter); in __post_watch_notification()
221 if (security_post_notification(watch->cred, cred, n) < 0) in __post_watch_notification()
240 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_size()
247 return -ENODEV; in watch_queue_set_size()
248 if (wqueue->notes) in watch_queue_set_size()
249 return -EBUSY; in watch_queue_set_size()
252 nr_notes > 512) /* TODO: choose a better hard limit */ in watch_queue_set_size()
253 return -EINVAL; in watch_queue_set_size()
255 nr_pages = (nr_notes + WATCH_QUEUE_NOTES_PER_PAGE - 1); in watch_queue_set_size()
257 user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_pages); in watch_queue_set_size()
259 if (nr_pages > pipe->max_usage && in watch_queue_set_size()
263 ret = -EPERM; in watch_queue_set_size()
278 pipe->max_usage = nr_pages; in watch_queue_set_size()
279 pipe->nr_accounted = nr_pages; in watch_queue_set_size()
281 ret = -ENOMEM; in watch_queue_set_size()
290 pages[i]->private = i * WATCH_QUEUE_NOTES_PER_PAGE; in watch_queue_set_size()
298 wqueue->notes = pages; in watch_queue_set_size()
299 wqueue->notes_bitmap = bitmap; in watch_queue_set_size()
300 wqueue->nr_pages = nr_pages; in watch_queue_set_size()
301 wqueue->nr_notes = nr_notes; in watch_queue_set_size()
305 while (--i >= 0) in watch_queue_set_size()
309 (void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted); in watch_queue_set_size()
314 * Set the filter on a watch queue.
319 struct watch_notification_type_filter *tf; in watch_queue_set_filter() local
323 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_filter()
327 return -ENODEV; in watch_queue_set_filter()
337 return -EFAULT; in watch_queue_set_filter()
341 return -EINVAL; in watch_queue_set_filter()
343 tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); in watch_queue_set_filter()
344 if (IS_ERR(tf)) in watch_queue_set_filter()
345 return PTR_ERR(tf); in watch_queue_set_filter()
347 ret = -EINVAL; in watch_queue_set_filter()
349 if ((tf[i].info_filter & ~tf[i].info_mask) || in watch_queue_set_filter()
350 tf[i].info_mask & WATCH_INFO_LENGTH) in watch_queue_set_filter()
353 if (tf[i].type >= WATCH_TYPE__NR) in watch_queue_set_filter()
359 * user-specified filters. in watch_queue_set_filter()
361 ret = -ENOMEM; in watch_queue_set_filter()
365 wfilter->nr_filters = nr_filter; in watch_queue_set_filter()
367 q = wfilter->filters; in watch_queue_set_filter()
369 if (tf[i].type >= WATCH_TYPE__NR) in watch_queue_set_filter()
372 q->type = tf[i].type; in watch_queue_set_filter()
373 q->info_filter = tf[i].info_filter; in watch_queue_set_filter()
374 q->info_mask = tf[i].info_mask; in watch_queue_set_filter()
375 q->subtype_filter[0] = tf[i].subtype_filter[0]; in watch_queue_set_filter()
376 __set_bit(q->type, wfilter->type_filter); in watch_queue_set_filter()
380 kfree(tf); in watch_queue_set_filter()
383 wfilter = rcu_replace_pointer(wqueue->filter, wfilter, in watch_queue_set_filter()
384 lockdep_is_held(&pipe->mutex)); in watch_queue_set_filter()
391 kfree(tf); in watch_queue_set_filter()
402 for (i = 0; i < wqueue->nr_pages; i++) in __put_watch_queue()
403 __free_page(wqueue->notes[i]); in __put_watch_queue()
404 kfree(wqueue->notes); in __put_watch_queue()
405 bitmap_free(wqueue->notes_bitmap); in __put_watch_queue()
407 wfilter = rcu_access_pointer(wqueue->filter); in __put_watch_queue()
414 * put_watch_queue - Dispose of a ref on a watchqueue.
419 kref_put(&wqueue->usage, __put_watch_queue); in put_watch_queue()
427 put_watch_queue(rcu_access_pointer(watch->queue)); in free_watch()
428 atomic_dec(&watch->cred->user->nr_watches); in free_watch()
429 put_cred(watch->cred); in free_watch()
437 call_rcu(&watch->rcu, free_watch); in __put_watch()
441 * Discard a watch.
445 kref_put(&watch->usage, __put_watch); in put_watch()
449 * init_watch - Initialise a watch
453 * Initialise a watch and set the watch queue.
457 kref_init(&watch->usage); in init_watch()
458 INIT_HLIST_NODE(&watch->list_node); in init_watch()
459 INIT_HLIST_NODE(&watch->queue_node); in init_watch()
460 rcu_assign_pointer(watch->queue, wqueue); in init_watch()
468 hlist_for_each_entry(w, &wlist->watchers, list_node) { in add_one_watch()
469 struct watch_queue *wq = rcu_access_pointer(w->queue); in add_one_watch()
470 if (wqueue == wq && watch->id == w->id) in add_one_watch()
471 return -EBUSY; in add_one_watch()
475 if (atomic_inc_return(&cred->user->nr_watches) > task_rlimit(current, RLIMIT_NOFILE)) { in add_one_watch()
476 atomic_dec(&cred->user->nr_watches); in add_one_watch()
477 return -EAGAIN; in add_one_watch()
480 watch->cred = get_cred(cred); in add_one_watch()
481 rcu_assign_pointer(watch->watch_list, wlist); in add_one_watch()
483 kref_get(&wqueue->usage); in add_one_watch()
484 kref_get(&watch->usage); in add_one_watch()
485 hlist_add_head(&watch->queue_node, &wqueue->watches); in add_one_watch()
486 hlist_add_head_rcu(&watch->list_node, &wlist->watchers); in add_one_watch()
491 * add_watch_to_object - Add a watch on an object to a watch list
495 * @watch->queue must have been set to point to the queue to post notifications
496 * to and the watch list of the object to be watched. @watch->cred must also
497 * have been set to the appropriate credentials and a ref taken on them.
505 int ret = -ENOENT; in add_watch_to_object()
509 wqueue = rcu_access_pointer(watch->queue); in add_watch_to_object()
511 spin_lock(&wlist->lock); in add_watch_to_object()
513 spin_unlock(&wlist->lock); in add_watch_to_object()
523 * remove_watch_from_object - Remove a watch or all watches from an object.
529 * Remove a specific watch or all watches from an object. A notification is
538 int ret = -EBADSLT; in remove_watch_from_object()
543 spin_lock(&wlist->lock); in remove_watch_from_object()
544 hlist_for_each_entry(watch, &wlist->watchers, list_node) { in remove_watch_from_object()
546 (watch->id == id && rcu_access_pointer(watch->queue) == wq)) in remove_watch_from_object()
549 spin_unlock(&wlist->lock); in remove_watch_from_object()
554 hlist_del_init_rcu(&watch->list_node); in remove_watch_from_object()
555 rcu_assign_pointer(watch->watch_list, NULL); in remove_watch_from_object()
556 spin_unlock(&wlist->lock); in remove_watch_from_object()
562 n.watch.info = watch->info_id | watch_sizeof(n.watch); in remove_watch_from_object()
565 n.watch.info = watch->info_id | watch_sizeof(n); in remove_watch_from_object()
567 wqueue = rcu_dereference(watch->queue); in remove_watch_from_object()
572 if (!hlist_unhashed(&watch->queue_node)) { in remove_watch_from_object()
573 hlist_del_init_rcu(&watch->queue_node); in remove_watch_from_object()
580 if (wlist->release_watch) { in remove_watch_from_object()
583 release_watch = wlist->release_watch; in remove_watch_from_object()
590 if (all && !hlist_empty(&wlist->watchers)) in remove_watch_from_object()
599 * Remove all the watches that are contributory to a queue. This has the
610 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
616 wqueue->pipe = NULL; in watch_queue_clear()
618 while (!hlist_empty(&wqueue->watches)) { in watch_queue_clear()
619 watch = hlist_entry(wqueue->watches.first, struct watch, queue_node); in watch_queue_clear()
620 hlist_del_init_rcu(&watch->queue_node); in watch_queue_clear()
621 /* We now own a ref on the watch. */ in watch_queue_clear()
622 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
625 * get the list lock - which would cause a deadlock if someone in watch_queue_clear()
627 * posting a notification. in watch_queue_clear()
629 wlist = rcu_dereference(watch->watch_list); in watch_queue_clear()
633 spin_lock(&wlist->lock); in watch_queue_clear()
635 release = !hlist_unhashed(&watch->list_node); in watch_queue_clear()
637 hlist_del_init_rcu(&watch->list_node); in watch_queue_clear()
638 rcu_assign_pointer(watch->watch_list, NULL); in watch_queue_clear()
640 /* We now own a second ref on the watch. */ in watch_queue_clear()
643 release_watch = wlist->release_watch; in watch_queue_clear()
644 spin_unlock(&wlist->lock); in watch_queue_clear()
660 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
663 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
668 * get_watch_queue - Get a watch queue from its file descriptor.
674 struct watch_queue *wqueue = ERR_PTR(-EINVAL); in get_watch_queue()
679 if (pipe && pipe->watch_queue) { in get_watch_queue()
680 wqueue = pipe->watch_queue; in get_watch_queue()
681 kref_get(&wqueue->usage); in get_watch_queue()
690 * Initialise a watch queue
698 return -ENOMEM; in watch_queue_init()
700 wqueue->pipe = pipe; in watch_queue_init()
701 kref_init(&wqueue->usage); in watch_queue_init()
702 spin_lock_init(&wqueue->lock); in watch_queue_init()
703 INIT_HLIST_HEAD(&wqueue->watches); in watch_queue_init()
705 pipe->watch_queue = wqueue; in watch_queue_init()