Files
android_kernel_xiaomi_sm8450/include/uapi/linux/watch_queue.h
David Howells c73be61ced 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>
2020-05-19 15:08:24 +01:00

79 lines
2.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI_LINUX_WATCH_QUEUE_H
#define _UAPI_LINUX_WATCH_QUEUE_H
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/ioctl.h>
#define O_NOTIFICATION_PIPE O_EXCL /* Parameter to pipe2() selecting notification pipe */
#define IOC_WATCH_QUEUE_SET_SIZE _IO('W', 0x60) /* Set the size in pages */
#define IOC_WATCH_QUEUE_SET_FILTER _IO('W', 0x61) /* Set the filter */
enum watch_notification_type {
WATCH_TYPE_META = 0, /* Special record */
WATCH_TYPE__NR = 1
};
enum watch_meta_notification_subtype {
WATCH_META_REMOVAL_NOTIFICATION = 0, /* Watched object was removed */
WATCH_META_LOSS_NOTIFICATION = 1, /* Data loss occurred */
};
/*
* Notification record header. This is aligned to 64-bits so that subclasses
* can contain __u64 fields.
*/
struct watch_notification {
__u32 type:24; /* enum watch_notification_type */
__u32 subtype:8; /* Type-specific subtype (filterable) */
__u32 info;
#define WATCH_INFO_LENGTH 0x0000007f /* Length of record */
#define WATCH_INFO_LENGTH__SHIFT 0
#define WATCH_INFO_ID 0x0000ff00 /* ID of watchpoint */
#define WATCH_INFO_ID__SHIFT 8
#define WATCH_INFO_TYPE_INFO 0xffff0000 /* Type-specific info */
#define WATCH_INFO_TYPE_INFO__SHIFT 16
#define WATCH_INFO_FLAG_0 0x00010000 /* Type-specific info, flag bit 0 */
#define WATCH_INFO_FLAG_1 0x00020000 /* ... */
#define WATCH_INFO_FLAG_2 0x00040000
#define WATCH_INFO_FLAG_3 0x00080000
#define WATCH_INFO_FLAG_4 0x00100000
#define WATCH_INFO_FLAG_5 0x00200000
#define WATCH_INFO_FLAG_6 0x00400000
#define WATCH_INFO_FLAG_7 0x00800000
};
/*
* Notification filtering rules (IOC_WATCH_QUEUE_SET_FILTER).
*/
struct watch_notification_type_filter {
__u32 type; /* Type to apply filter to */
__u32 info_filter; /* Filter on watch_notification::info */
__u32 info_mask; /* Mask of relevant bits in info_filter */
__u32 subtype_filter[8]; /* Bitmask of subtypes to filter on */
};
struct watch_notification_filter {
__u32 nr_filters; /* Number of filters */
__u32 __reserved; /* Must be 0 */
struct watch_notification_type_filter filters[];
};
/*
* Extended watch removal notification. This is used optionally if the type
* wants to indicate an identifier for the object being watched, if there is
* such. This can be distinguished by the length.
*
* type -> WATCH_TYPE_META
* subtype -> WATCH_META_REMOVAL_NOTIFICATION
*/
struct watch_notification_removal {
struct watch_notification watch;
__u64 id; /* Type-dependent identifier */
};
#endif /* _UAPI_LINUX_WATCH_QUEUE_H */