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->index; 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()
272 ret = -ENOMEM; in watch_queue_set_size()
281 pages[i]->index = i * WATCH_QUEUE_NOTES_PER_PAGE; in watch_queue_set_size()
289 wqueue->notes = pages; in watch_queue_set_size()
290 wqueue->notes_bitmap = bitmap; in watch_queue_set_size()
291 wqueue->nr_pages = nr_pages; in watch_queue_set_size()
292 wqueue->nr_notes = nr_notes; in watch_queue_set_size()
296 while (--i >= 0) in watch_queue_set_size()
300 (void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted); in watch_queue_set_size()
305 * Set the filter on a watch queue.
310 struct watch_notification_type_filter *tf; in watch_queue_set_filter() local
314 struct watch_queue *wqueue = pipe->watch_queue; in watch_queue_set_filter()
318 return -ENODEV; in watch_queue_set_filter()
328 return -EFAULT; in watch_queue_set_filter()
332 return -EINVAL; in watch_queue_set_filter()
334 tf = memdup_array_user(_filter->filters, filter.nr_filters, sizeof(*tf)); in watch_queue_set_filter()
335 if (IS_ERR(tf)) in watch_queue_set_filter()
336 return PTR_ERR(tf); in watch_queue_set_filter()
338 ret = -EINVAL; in watch_queue_set_filter()
340 if ((tf[i].info_filter & ~tf[i].info_mask) || in watch_queue_set_filter()
341 tf[i].info_mask & WATCH_INFO_LENGTH) in watch_queue_set_filter()
344 if (tf[i].type >= WATCH_TYPE__NR) in watch_queue_set_filter()
350 * user-specified filters. in watch_queue_set_filter()
352 ret = -ENOMEM; in watch_queue_set_filter()
356 wfilter->nr_filters = nr_filter; in watch_queue_set_filter()
358 q = wfilter->filters; in watch_queue_set_filter()
360 if (tf[i].type >= WATCH_TYPE__NR) in watch_queue_set_filter()
363 q->type = tf[i].type; in watch_queue_set_filter()
364 q->info_filter = tf[i].info_filter; in watch_queue_set_filter()
365 q->info_mask = tf[i].info_mask; in watch_queue_set_filter()
366 q->subtype_filter[0] = tf[i].subtype_filter[0]; in watch_queue_set_filter()
367 __set_bit(q->type, wfilter->type_filter); in watch_queue_set_filter()
371 kfree(tf); in watch_queue_set_filter()
374 wfilter = rcu_replace_pointer(wqueue->filter, wfilter, in watch_queue_set_filter()
375 lockdep_is_held(&pipe->mutex)); in watch_queue_set_filter()
382 kfree(tf); in watch_queue_set_filter()
393 for (i = 0; i < wqueue->nr_pages; i++) in __put_watch_queue()
394 __free_page(wqueue->notes[i]); in __put_watch_queue()
395 kfree(wqueue->notes); in __put_watch_queue()
396 bitmap_free(wqueue->notes_bitmap); in __put_watch_queue()
398 wfilter = rcu_access_pointer(wqueue->filter); in __put_watch_queue()
405 * put_watch_queue - Dispose of a ref on a watchqueue.
410 kref_put(&wqueue->usage, __put_watch_queue); in put_watch_queue()
418 put_watch_queue(rcu_access_pointer(watch->queue)); in free_watch()
419 atomic_dec(&watch->cred->user->nr_watches); in free_watch()
420 put_cred(watch->cred); in free_watch()
428 call_rcu(&watch->rcu, free_watch); in __put_watch()
432 * Discard a watch.
436 kref_put(&watch->usage, __put_watch); in put_watch()
440 * init_watch - Initialise a watch
444 * Initialise a watch and set the watch queue.
448 kref_init(&watch->usage); in init_watch()
449 INIT_HLIST_NODE(&watch->list_node); in init_watch()
450 INIT_HLIST_NODE(&watch->queue_node); in init_watch()
451 rcu_assign_pointer(watch->queue, wqueue); in init_watch()
459 hlist_for_each_entry(w, &wlist->watchers, list_node) { in add_one_watch()
460 struct watch_queue *wq = rcu_access_pointer(w->queue); in add_one_watch()
461 if (wqueue == wq && watch->id == w->id) in add_one_watch()
462 return -EBUSY; in add_one_watch()
466 if (atomic_inc_return(&cred->user->nr_watches) > task_rlimit(current, RLIMIT_NOFILE)) { in add_one_watch()
467 atomic_dec(&cred->user->nr_watches); in add_one_watch()
468 return -EAGAIN; in add_one_watch()
471 watch->cred = get_cred(cred); in add_one_watch()
472 rcu_assign_pointer(watch->watch_list, wlist); in add_one_watch()
474 kref_get(&wqueue->usage); in add_one_watch()
475 kref_get(&watch->usage); in add_one_watch()
476 hlist_add_head(&watch->queue_node, &wqueue->watches); in add_one_watch()
477 hlist_add_head_rcu(&watch->list_node, &wlist->watchers); in add_one_watch()
482 * add_watch_to_object - Add a watch on an object to a watch list
486 * @watch->queue must have been set to point to the queue to post notifications
487 * to and the watch list of the object to be watched. @watch->cred must also
488 * have been set to the appropriate credentials and a ref taken on them.
496 int ret = -ENOENT; in add_watch_to_object()
500 wqueue = rcu_access_pointer(watch->queue); in add_watch_to_object()
502 spin_lock(&wlist->lock); in add_watch_to_object()
504 spin_unlock(&wlist->lock); in add_watch_to_object()
514 * remove_watch_from_object - Remove a watch or all watches from an object.
520 * Remove a specific watch or all watches from an object. A notification is
529 int ret = -EBADSLT; in remove_watch_from_object()
534 spin_lock(&wlist->lock); in remove_watch_from_object()
535 hlist_for_each_entry(watch, &wlist->watchers, list_node) { in remove_watch_from_object()
537 (watch->id == id && rcu_access_pointer(watch->queue) == wq)) in remove_watch_from_object()
540 spin_unlock(&wlist->lock); in remove_watch_from_object()
545 hlist_del_init_rcu(&watch->list_node); in remove_watch_from_object()
546 rcu_assign_pointer(watch->watch_list, NULL); in remove_watch_from_object()
547 spin_unlock(&wlist->lock); in remove_watch_from_object()
553 n.watch.info = watch->info_id | watch_sizeof(n.watch); in remove_watch_from_object()
556 n.watch.info = watch->info_id | watch_sizeof(n); in remove_watch_from_object()
558 wqueue = rcu_dereference(watch->queue); in remove_watch_from_object()
563 if (!hlist_unhashed(&watch->queue_node)) { in remove_watch_from_object()
564 hlist_del_init_rcu(&watch->queue_node); in remove_watch_from_object()
571 if (wlist->release_watch) { in remove_watch_from_object()
574 release_watch = wlist->release_watch; in remove_watch_from_object()
581 if (all && !hlist_empty(&wlist->watchers)) in remove_watch_from_object()
590 * Remove all the watches that are contributory to a queue. This has the
601 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
607 wqueue->pipe = NULL; in watch_queue_clear()
609 while (!hlist_empty(&wqueue->watches)) { in watch_queue_clear()
610 watch = hlist_entry(wqueue->watches.first, struct watch, queue_node); in watch_queue_clear()
611 hlist_del_init_rcu(&watch->queue_node); in watch_queue_clear()
612 /* We now own a ref on the watch. */ in watch_queue_clear()
613 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
616 * get the list lock - which would cause a deadlock if someone in watch_queue_clear()
618 * posting a notification. in watch_queue_clear()
620 wlist = rcu_dereference(watch->watch_list); in watch_queue_clear()
624 spin_lock(&wlist->lock); in watch_queue_clear()
626 release = !hlist_unhashed(&watch->list_node); in watch_queue_clear()
628 hlist_del_init_rcu(&watch->list_node); in watch_queue_clear()
629 rcu_assign_pointer(watch->watch_list, NULL); in watch_queue_clear()
631 /* We now own a second ref on the watch. */ in watch_queue_clear()
634 release_watch = wlist->release_watch; in watch_queue_clear()
635 spin_unlock(&wlist->lock); in watch_queue_clear()
651 spin_lock_bh(&wqueue->lock); in watch_queue_clear()
654 spin_unlock_bh(&wqueue->lock); in watch_queue_clear()
659 * get_watch_queue - Get a watch queue from its file descriptor.
665 struct watch_queue *wqueue = ERR_PTR(-EINVAL); in get_watch_queue()
671 if (pipe && pipe->watch_queue) { in get_watch_queue()
672 wqueue = pipe->watch_queue; in get_watch_queue()
673 kref_get(&wqueue->usage); in get_watch_queue()
683 * Initialise a watch queue
691 return -ENOMEM; in watch_queue_init()
693 wqueue->pipe = pipe; in watch_queue_init()
694 kref_init(&wqueue->usage); in watch_queue_init()
695 spin_lock_init(&wqueue->lock); in watch_queue_init()
696 INIT_HLIST_HEAD(&wqueue->watches); in watch_queue_init()
698 pipe->watch_queue = wqueue; in watch_queue_init()