Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Watch queue and general notification mechanism, built on pipes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * See Documentation/watch_queue.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define pr_fmt(fmt) "watchq: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/cred.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/watch_queue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/pipe_fs_i.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) MODULE_DESCRIPTION("Watch queue");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) MODULE_AUTHOR("Red Hat, Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define WATCH_QUEUE_NOTE_SIZE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static void watch_queue_pipe_buf_release(struct pipe_inode_info *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 					 struct pipe_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	struct watch_queue *wqueue = (struct watch_queue *)buf->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	unsigned int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	/* We need to work out which note within the page this refers to, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	 * the note might have been maximum size, so merely ANDing the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	 * off doesn't work.  OTOH, the note must've been more than zero size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	bit = buf->offset + buf->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if ((bit & (WATCH_QUEUE_NOTE_SIZE - 1)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		bit -= WATCH_QUEUE_NOTE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	bit /= WATCH_QUEUE_NOTE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	page = buf->page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	bit += page->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	set_bit(bit, wqueue->notes_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	generic_pipe_buf_release(pipe, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) // No try_steal function => no stealing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define watch_queue_pipe_buf_try_steal NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /* New data written to a pipe may be appended to a buffer with this type. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static const struct pipe_buf_operations watch_queue_pipe_buf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	.release	= watch_queue_pipe_buf_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	.try_steal	= watch_queue_pipe_buf_try_steal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	.get		= generic_pipe_buf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * Post a notification to a watch queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static bool post_one_notification(struct watch_queue *wqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				  struct watch_notification *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct pipe_inode_info *pipe = wqueue->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct pipe_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	unsigned int head, tail, mask, note, offset, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	bool done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (!pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	spin_lock_irq(&pipe->rd_wait.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (wqueue->defunct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	mask = pipe->ring_size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	head = pipe->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	tail = pipe->tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (pipe_full(head, tail, pipe->ring_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		goto lost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	note = find_first_bit(wqueue->notes_bitmap, wqueue->nr_notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (note >= wqueue->nr_notes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		goto lost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	page = wqueue->notes[note / WATCH_QUEUE_NOTES_PER_PAGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	offset = note % WATCH_QUEUE_NOTES_PER_PAGE * WATCH_QUEUE_NOTE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	get_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	len = n->info & WATCH_INFO_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	p = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	memcpy(p + offset, n, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	kunmap_atomic(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	buf = &pipe->bufs[head & mask];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	buf->page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	buf->private = (unsigned long)wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	buf->ops = &watch_queue_pipe_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	buf->offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	buf->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	buf->flags = PIPE_BUF_FLAG_WHOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (!test_and_clear_bit(note, wqueue->notes_bitmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		spin_unlock_irq(&pipe->rd_wait.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	wake_up_interruptible_sync_poll_locked(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	spin_unlock_irq(&pipe->rd_wait.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) lost:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	buf = &pipe->bufs[(head - 1) & mask];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	buf->flags |= PIPE_BUF_FLAG_LOSS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * Apply filter rules to a notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static bool filter_watch_notification(const struct watch_filter *wf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				      const struct watch_notification *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	const struct watch_type_filter *wt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	unsigned int st_bits = sizeof(wt->subtype_filter[0]) * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	unsigned int st_index = n->subtype / st_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	unsigned int st_bit = 1U << (n->subtype % st_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (!test_bit(n->type, wf->type_filter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	for (i = 0; i < wf->nr_filters; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		wt = &wf->filters[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		if (n->type == wt->type &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		    (wt->subtype_filter[st_index] & st_bit) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		    (n->info & wt->info_mask) == wt->info_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	return false; /* If there is a filter, the default is to reject. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  * __post_watch_notification - Post an event notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * @wlist: The watch list to post the event to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * @n: The notification record to post.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * @cred: The creds of the process that triggered the notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * @id: The ID to match on the watch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * Post a notification of an event into a set of watch queues and let the users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * know.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * The size of the notification should be set in n->info & WATCH_INFO_LENGTH and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * should be in units of sizeof(*n).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) void __post_watch_notification(struct watch_list *wlist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			       struct watch_notification *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			       const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			       u64 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	const struct watch_filter *wf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct watch_queue *wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct watch *watch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	if (((n->info & WATCH_INFO_LENGTH) >> WATCH_INFO_LENGTH__SHIFT) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	hlist_for_each_entry_rcu(watch, &wlist->watchers, list_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if (watch->id != id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		n->info &= ~WATCH_INFO_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		n->info |= watch->info_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		wqueue = rcu_dereference(watch->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		wf = rcu_dereference(wqueue->filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		if (wf && !filter_watch_notification(wf, n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		if (security_post_notification(watch->cred, cred, n) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		post_one_notification(wqueue, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) EXPORT_SYMBOL(__post_watch_notification);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Allocate sufficient pages to preallocation for the requested number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  * notifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct watch_queue *wqueue = pipe->watch_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	unsigned long *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	unsigned long user_bufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	unsigned int bmsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	int ret, i, nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	if (!wqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (wqueue->notes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (nr_notes < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	    nr_notes > 512) /* TODO: choose a better hard limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	nr_pages = (nr_notes + WATCH_QUEUE_NOTES_PER_PAGE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	nr_pages /= WATCH_QUEUE_NOTES_PER_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (nr_pages > pipe->max_usage &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	    (too_many_pipe_buffers_hard(user_bufs) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	     too_many_pipe_buffers_soft(user_bufs)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	    pipe_is_unprivileged_user()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	nr_notes = nr_pages * WATCH_QUEUE_NOTES_PER_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	ret = pipe_resize_ring(pipe, roundup_pow_of_two(nr_notes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	pages = kcalloc(sizeof(struct page *), nr_pages, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	if (!pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	for (i = 0; i < nr_pages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		pages[i] = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		if (!pages[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			goto error_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		pages[i]->index = i * WATCH_QUEUE_NOTES_PER_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	bmsize = (nr_notes + BITS_PER_LONG - 1) / BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	bmsize *= sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	bitmap = kmalloc(bmsize, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (!bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		goto error_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	memset(bitmap, 0xff, bmsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	wqueue->notes = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	wqueue->notes_bitmap = bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	wqueue->nr_pages = nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	wqueue->nr_notes = nr_notes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) error_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		__free_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	kfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	(void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * Set the filter on a watch queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) long watch_queue_set_filter(struct pipe_inode_info *pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			    struct watch_notification_filter __user *_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct watch_notification_type_filter *tf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	struct watch_notification_filter filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	struct watch_type_filter *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	struct watch_filter *wfilter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	struct watch_queue *wqueue = pipe->watch_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int ret, nr_filter = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (!wqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (!_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		/* Remove the old filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		wfilter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		goto set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	/* Grab the user's filter specification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (copy_from_user(&filter, _filter, sizeof(filter)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (filter.nr_filters == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	    filter.nr_filters > 16 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	    filter.__reserved != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	tf = memdup_user(_filter->filters, filter.nr_filters * sizeof(*tf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (IS_ERR(tf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		return PTR_ERR(tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	for (i = 0; i < filter.nr_filters; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		if ((tf[i].info_filter & ~tf[i].info_mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		    tf[i].info_mask & WATCH_INFO_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			goto err_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		/* Ignore any unknown types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		if (tf[i].type >= WATCH_TYPE__NR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		nr_filter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	/* Now we need to build the internal filter from only the relevant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	 * user-specified filters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	wfilter = kzalloc(struct_size(wfilter, filters, nr_filter), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	if (!wfilter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		goto err_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	wfilter->nr_filters = nr_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	q = wfilter->filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	for (i = 0; i < filter.nr_filters; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		if (tf[i].type >= WATCH_TYPE__NR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		q->type			= tf[i].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		q->info_filter		= tf[i].info_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		q->info_mask		= tf[i].info_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		q->subtype_filter[0]	= tf[i].subtype_filter[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		__set_bit(q->type, wfilter->type_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		q++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	kfree(tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	pipe_lock(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	wfilter = rcu_replace_pointer(wqueue->filter, wfilter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 				      lockdep_is_held(&pipe->mutex));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	pipe_unlock(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (wfilter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		kfree_rcu(wfilter, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) err_filter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	kfree(tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static void __put_watch_queue(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	struct watch_queue *wqueue =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		container_of(kref, struct watch_queue, usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	struct watch_filter *wfilter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	for (i = 0; i < wqueue->nr_pages; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		__free_page(wqueue->notes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	kfree(wqueue->notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	bitmap_free(wqueue->notes_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	wfilter = rcu_access_pointer(wqueue->filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (wfilter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		kfree_rcu(wfilter, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	kfree_rcu(wqueue, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  * put_watch_queue - Dispose of a ref on a watchqueue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  * @wqueue: The watch queue to unref.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) void put_watch_queue(struct watch_queue *wqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	kref_put(&wqueue->usage, __put_watch_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) EXPORT_SYMBOL(put_watch_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static void free_watch(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	struct watch *watch = container_of(rcu, struct watch, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	put_watch_queue(rcu_access_pointer(watch->queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	atomic_dec(&watch->cred->user->nr_watches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	put_cred(watch->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	kfree(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static void __put_watch(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	struct watch *watch = container_of(kref, struct watch, usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	call_rcu(&watch->rcu, free_watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * Discard a watch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static void put_watch(struct watch *watch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	kref_put(&watch->usage, __put_watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  * init_watch_queue - Initialise a watch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  * @watch: The watch to initialise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  * @wqueue: The queue to assign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  * Initialise a watch and set the watch queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) void init_watch(struct watch *watch, struct watch_queue *wqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	kref_init(&watch->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	INIT_HLIST_NODE(&watch->list_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	INIT_HLIST_NODE(&watch->queue_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	rcu_assign_pointer(watch->queue, wqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)  * add_watch_to_object - Add a watch on an object to a watch list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)  * @watch: The watch to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)  * @wlist: The watch list to add to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  * @watch->queue must have been set to point to the queue to post notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  * to and the watch list of the object to be watched.  @watch->cred must also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  * have been set to the appropriate credentials and a ref taken on them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)  * The caller must pin the queue and the list both and must hold the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)  * locked against racing watch additions/removals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int add_watch_to_object(struct watch *watch, struct watch_list *wlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	struct watch_queue *wqueue = rcu_access_pointer(watch->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	struct watch *w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	hlist_for_each_entry(w, &wlist->watchers, list_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		struct watch_queue *wq = rcu_access_pointer(w->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		if (wqueue == wq && watch->id == w->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	watch->cred = get_current_cred();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	rcu_assign_pointer(watch->watch_list, wlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (atomic_inc_return(&watch->cred->user->nr_watches) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	    task_rlimit(current, RLIMIT_NOFILE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		atomic_dec(&watch->cred->user->nr_watches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		put_cred(watch->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	spin_lock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	kref_get(&wqueue->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	kref_get(&watch->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	hlist_add_head(&watch->queue_node, &wqueue->watches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	spin_unlock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	hlist_add_head(&watch->list_node, &wlist->watchers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) EXPORT_SYMBOL(add_watch_to_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  * remove_watch_from_object - Remove a watch or all watches from an object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)  * @wlist: The watch list to remove from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)  * @wq: The watch queue of interest (ignored if @all is true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)  * @id: The ID of the watch to remove (ignored if @all is true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)  * @all: True to remove all objects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)  * Remove a specific watch or all watches from an object.  A notification is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)  * sent to the watcher to tell them that this happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int remove_watch_from_object(struct watch_list *wlist, struct watch_queue *wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			     u64 id, bool all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	struct watch_notification_removal n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	struct watch_queue *wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	struct watch *watch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	int ret = -EBADSLT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	spin_lock(&wlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	hlist_for_each_entry(watch, &wlist->watchers, list_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		if (all ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		    (watch->id == id && rcu_access_pointer(watch->queue) == wq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	spin_unlock(&wlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	hlist_del_init_rcu(&watch->list_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	rcu_assign_pointer(watch->watch_list, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	spin_unlock(&wlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	/* We now own the reference on watch that used to belong to wlist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	n.watch.type = WATCH_TYPE_META;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	n.watch.subtype = WATCH_META_REMOVAL_NOTIFICATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	n.watch.info = watch->info_id | watch_sizeof(n.watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	n.id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (id != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		n.watch.info = watch->info_id | watch_sizeof(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	wqueue = rcu_dereference(watch->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	/* We don't need the watch list lock for the next bit as RCU is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	 * protecting *wqueue from deallocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (wqueue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		post_one_notification(wqueue, &n.watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		spin_lock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (!hlist_unhashed(&watch->queue_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			hlist_del_init_rcu(&watch->queue_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			put_watch(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		spin_unlock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (wlist->release_watch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		void (*release_watch)(struct watch *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		release_watch = wlist->release_watch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		(*release_watch)(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	put_watch(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	if (all && !hlist_empty(&wlist->watchers))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) EXPORT_SYMBOL(remove_watch_from_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)  * Remove all the watches that are contributory to a queue.  This has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  * potential to race with removal of the watches by the destruction of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  * objects being watched or with the distribution of notifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) void watch_queue_clear(struct watch_queue *wqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	struct watch_list *wlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	struct watch *watch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	bool release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	spin_lock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	/* Prevent new notifications from being stored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	wqueue->defunct = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	while (!hlist_empty(&wqueue->watches)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		watch = hlist_entry(wqueue->watches.first, struct watch, queue_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		hlist_del_init_rcu(&watch->queue_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		/* We now own a ref on the watch. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		spin_unlock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		/* We can't do the next bit under the queue lock as we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		 * get the list lock - which would cause a deadlock if someone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		 * was removing from the opposite direction at the same time or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		 * posting a notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		wlist = rcu_dereference(watch->watch_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		if (wlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			void (*release_watch)(struct watch *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 			spin_lock(&wlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 			release = !hlist_unhashed(&watch->list_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 			if (release) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 				hlist_del_init_rcu(&watch->list_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 				rcu_assign_pointer(watch->watch_list, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 				/* We now own a second ref on the watch. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			release_watch = wlist->release_watch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			spin_unlock(&wlist->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			if (release) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 				if (release_watch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 					rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 					/* This might need to call dput(), so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 					 * we have to drop all the locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 					(*release_watch)(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 					rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 				put_watch(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		put_watch(watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		spin_lock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	spin_unlock_bh(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)  * get_watch_queue - Get a watch queue from its file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)  * @fd: The fd to query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct watch_queue *get_watch_queue(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	struct pipe_inode_info *pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	struct watch_queue *wqueue = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	if (f.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		pipe = get_pipe_info(f.file, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		if (pipe && pipe->watch_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 			wqueue = pipe->watch_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			kref_get(&wqueue->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	return wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) EXPORT_SYMBOL(get_watch_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)  * Initialise a watch queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) int watch_queue_init(struct pipe_inode_info *pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	struct watch_queue *wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	wqueue = kzalloc(sizeof(*wqueue), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	if (!wqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	wqueue->pipe = pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	kref_init(&wqueue->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	spin_lock_init(&wqueue->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	INIT_HLIST_HEAD(&wqueue->watches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	pipe->watch_queue = wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }