pipe: Add general notification queue support
Make it possible to have a general notification queue built on top of a
standard pipe. Notifications are 'spliced' into the pipe and then read
out. splice(), vmsplice() and sendfile() are forbidden on pipes used for
notifications as post_one_notification() cannot take pipe->mutex. This
means that notifications could be posted in between individual pipe
buffers, making iov_iter_revert() difficult to effect.
The way the notification queue is used is:
(1) An application opens a pipe with a special flag and indicates the
number of messages it wishes to be able to queue at once (this can
only be set once):
pipe2(fds, O_NOTIFICATION_PIPE);
ioctl(fds[0], IOC_WATCH_QUEUE_SET_SIZE, queue_depth);
(2) The application then uses poll() and read() as normal to extract data
from the pipe. read() will return multiple notifications if the
buffer is big enough, but it will not split a notification across
buffers - rather it will return a short read or EMSGSIZE.
Notification messages include a length in the header so that the
caller can split them up.
Each message has a header that describes it:
struct watch_notification {
__u32 type:24;
__u32 subtype:8;
__u32 info;
};
The type indicates the source (eg. mount tree changes, superblock events,
keyring changes, block layer events) and the subtype indicates the event
type (eg. mount, unmount; EIO, EDQUOT; link, unlink). The info field
indicates a number of things, including the entry length, an ID assigned to
a watchpoint contributing to this buffer and type-specific flags.
Supplementary data, such as the key ID that generated an event, can be
attached in additional slots. The maximum message size is 127 bytes.
Messages may not be padded or aligned, so there is no guarantee, for
example, that the notification type will be on a 4-byte bounary.
Signed-off-by:
David Howells <dhowells@redhat.com>
- Documentation/userspace-api/ioctl/ioctl-number.rst 1 addition, 0 deletionsDocumentation/userspace-api/ioctl/ioctl-number.rst
- Documentation/watch_queue.rst 339 additions, 0 deletionsDocumentation/watch_queue.rst
- fs/pipe.c 137 additions, 69 deletionsfs/pipe.c
- fs/splice.c 6 additions, 6 deletionsfs/splice.c
- include/linux/pipe_fs_i.h 18 additions, 1 deletioninclude/linux/pipe_fs_i.h
- include/linux/watch_queue.h 127 additions, 0 deletionsinclude/linux/watch_queue.h
- include/uapi/linux/watch_queue.h 20 additions, 0 deletionsinclude/uapi/linux/watch_queue.h
- init/Kconfig 12 additions, 0 deletionsinit/Kconfig
- kernel/Makefile 1 addition, 0 deletionskernel/Makefile
- kernel/watch_queue.c 657 additions, 0 deletionskernel/watch_queue.c
-
mentioned in commit d729d4e9
-
mentioned in commit 2039900a
-
mentioned in commit e2b52ca4
-
mentioned in commit 880acbb7
-
mentioned in commit 06ab8444
-
mentioned in commit 24d26813
-
mentioned in commit ec03510e
-
mentioned in commit 648895da
-
mentioned in commit 8275b669
-
mentioned in commit b022b6a0
-
mentioned in commit 82ff8a22
-
mentioned in commit ffb8fd39
-
mentioned in commit ccd03c30
-
mentioned in commit 1b09f28f
-
mentioned in commit eb38c2e9
-
mentioned in commit d453d0e5
-
mentioned in commit eef9afda
-
mentioned in commit b36588eb
-
mentioned in commit 70bbc085
-
mentioned in commit 2f331b8d
-
mentioned in commit d7e05190
-
mentioned in commit 36198e39
-
mentioned in commit ab36cca5
-
mentioned in commit 6cb5c7e1
-
mentioned in commit c993ee0f
-
mentioned in commit 3b4c0371
-
mentioned in commit db8facfc
-
mentioned in commit 2ed147f0
-
mentioned in commit 4edc0760
-
mentioned in commit 7ea1a012
-
mentioned in commit 96a4d891
-
mentioned in commit c1853fba
-
mentioned in commit 3d8dcf27
-
mentioned in commit a635415a
-
mentioned in commit 3963a5d1
-
mentioned in commit 375cd253
-
mentioned in commit b4902070
-
mentioned in commit f0d6abaa
-
mentioned in commit 71c60380
-
mentioned in commit b5fe8c47
-
mentioned in commit a2c2b6c9
-
mentioned in commit 2bd9e6cd
-
mentioned in commit ba9c27ba
-
mentioned in commit d9c19428