diff options
Diffstat (limited to 'ipc/kdbus/message.h')
| -rw-r--r-- | ipc/kdbus/message.h | 179 |
1 files changed, 83 insertions, 96 deletions
diff --git a/ipc/kdbus/message.h b/ipc/kdbus/message.h index af4775850235..298f9c99dfcf 100644 --- a/ipc/kdbus/message.h +++ b/ipc/kdbus/message.h @@ -14,120 +14,107 @@ #ifndef __KDBUS_MESSAGE_H #define __KDBUS_MESSAGE_H -#include "util.h" -#include "metadata.h" +#include <linux/fs.h> +#include <linux/kref.h> +#include <uapi/linux/kdbus.h> -/** - * enum kdbus_msg_data_type - Type of kdbus_msg_data payloads - * @KDBUS_MSG_DATA_VEC: Data vector provided by user-space - * @KDBUS_MSG_DATA_MEMFD: Memfd payload - */ -enum kdbus_msg_data_type { - KDBUS_MSG_DATA_VEC, - KDBUS_MSG_DATA_MEMFD, -}; - -/** - * struct kdbus_msg_data - Data payload as stored by messages - * @type: Type of payload (KDBUS_MSG_DATA_*) - * @size: Size of the described payload - * @off: The offset, relative to the vec slice - * @start: Offset inside the memfd - * @file: Backing file referenced by the memfd - */ -struct kdbus_msg_data { - unsigned int type; - u64 size; - - union { - struct { - u64 off; - } vec; - struct { - u64 start; - struct file *file; - } memfd; - }; -}; +struct kdbus_bus; +struct kdbus_conn; +struct kdbus_meta_conn; +struct kdbus_meta_proc; +struct kdbus_pool_slice; /** - * struct kdbus_kmsg_resources - resources of a message + * struct kdbus_gaps - gaps in message to be filled later * @kref: Reference counter - * @dst_name: Short-cut to msg for faster lookup - * @fds: Array of file descriptors to pass - * @fds_count: Number of file descriptors to pass - * @data: Array of data payloads - * @vec_count: Number of VEC entries - * @memfd_count: Number of MEMFD entries in @data - * @data_count: Sum of @vec_count + @memfd_count + * @n_memfd_offs: Number of memfds + * @memfd_offs: Offsets of kdbus_memfd items in target slice + * @n_fds: Number of fds + * @fds: Array of sent fds + * @fds_offset: Offset of fd-array in target slice + * + * The 'gaps' object is used to track data that is needed to fill gaps in a + * message at RECV time. Usually, we try to compile the whole message at SEND + * time. This has the advantage, that we don't have to cache any information and + * can keep the memory consumption small. Furthermore, all copy operations can + * be combined into a single function call, which speeds up transactions + * considerably. + * However, things like file-descriptors can only be fully installed at RECV + * time. The gaps object tracks this data and pins it until a message is + * received. The gaps object is shared between all receivers of the same + * message. */ -struct kdbus_msg_resources { +struct kdbus_gaps { struct kref kref; - const char *dst_name; - struct file **fds; - unsigned int fds_count; + /* state tracking for KDBUS_ITEM_PAYLOAD_MEMFD entries */ + size_t n_memfds; + u64 *memfd_offsets; + struct file **memfd_files; - struct kdbus_msg_data *data; - size_t vec_count; - size_t memfd_count; - size_t data_count; + /* state tracking for KDBUS_ITEM_FDS */ + size_t n_fds; + struct file **fd_files; + u64 fd_offset; }; -struct kdbus_msg_resources * -kdbus_msg_resources_ref(struct kdbus_msg_resources *r); -struct kdbus_msg_resources * -kdbus_msg_resources_unref(struct kdbus_msg_resources *r); +struct kdbus_gaps *kdbus_gaps_ref(struct kdbus_gaps *gaps); +struct kdbus_gaps *kdbus_gaps_unref(struct kdbus_gaps *gaps); +int kdbus_gaps_install(struct kdbus_gaps *gaps, struct kdbus_pool_slice *slice, + bool *out_incomplete); /** - * struct kdbus_kmsg - internal message handling data - * @seq: Domain-global message sequence number - * @notify_type: Short-cut for faster lookup - * @notify_old_id: Short-cut for faster lookup - * @notify_new_id: Short-cut for faster lookup - * @notify_name: Short-cut for faster lookup - * @dst_name_id: Short-cut to msg for faster lookup - * @bloom_filter: Bloom filter to match message properties - * @bloom_generation: Generation of bloom element set - * @notify_entry: List of kernel-generated notifications - * @iov: Array of iovec, describing the payload to copy - * @iov_count: Number of array members in @iov - * @pool_size: Overall size of inlined data referenced by @iov - * @proc_meta: Appended SCM-like metadata of the sending process - * @conn_meta: Appended SCM-like metadata of the sending connection - * @res: Message resources - * @msg: Message from or to userspace + * struct kdbus_staging - staging area to import messages + * @msg: User-supplied message + * @gaps: Gaps-object created during import (or NULL if empty) + * @msg_seqnum: Message sequence number + * @notify_entry: Entry into list of kernel-generated notifications + * @i_payload: Current relative index of start of payload + * @n_payload: Total number of bytes needed for payload + * @n_parts: Number of parts + * @parts: Array of iovecs that make up the whole message + * @meta_proc: Process metadata of the sender (or NULL if empty) + * @meta_conn: Connection metadata of the sender (or NULL if empty) + * @bloom_filter: Pointer to the bloom-item in @msg, or NULL + * @dst_name: Pointer to the dst-name-item in @msg, or NULL + * @notify: Pointer to the notification item in @msg, or NULL + * + * The kdbus_staging object is a temporary staging area to import user-supplied + * messages into the kernel. It is only used during SEND and dropped once the + * message is queued. Any data that cannot be collected during SEND, is + * collected in a kdbus_gaps object and attached to the message queue. */ -struct kdbus_kmsg { - u64 seq; - u64 notify_type; - u64 notify_old_id; - u64 notify_new_id; - const char *notify_name; - - u64 dst_name_id; - const struct kdbus_bloom_filter *bloom_filter; - u64 bloom_generation; +struct kdbus_staging { + struct kdbus_msg *msg; + struct kdbus_gaps *gaps; + u64 msg_seqnum; struct list_head notify_entry; - struct iovec *iov; - size_t iov_count; - u64 pool_size; + /* crafted iovecs to copy the message */ + size_t i_payload; + size_t n_payload; + size_t n_parts; + struct iovec *parts; - struct kdbus_meta_proc *proc_meta; - struct kdbus_meta_conn *conn_meta; - struct kdbus_msg_resources *res; + /* metadata state */ + struct kdbus_meta_proc *meta_proc; + struct kdbus_meta_conn *meta_conn; - /* variable size, must be the last member */ - struct kdbus_msg msg; + /* cached pointers into @msg */ + const struct kdbus_bloom_filter *bloom_filter; + const char *dst_name; + struct kdbus_item *notify; }; -struct kdbus_bus; -struct kdbus_conn; - -struct kdbus_kmsg *kdbus_kmsg_new(struct kdbus_bus *bus, size_t extra_size); -struct kdbus_kmsg *kdbus_kmsg_new_from_cmd(struct kdbus_conn *conn, - struct kdbus_cmd_send *cmd_send); -void kdbus_kmsg_free(struct kdbus_kmsg *kmsg); +struct kdbus_staging *kdbus_staging_new_kernel(struct kdbus_bus *bus, + u64 dst, u64 cookie_timeout, + size_t it_size, size_t it_type); +struct kdbus_staging *kdbus_staging_new_user(struct kdbus_bus *bus, + struct kdbus_cmd_send *cmd, + struct kdbus_msg *msg); +struct kdbus_staging *kdbus_staging_free(struct kdbus_staging *staging); +struct kdbus_pool_slice *kdbus_staging_emit(struct kdbus_staging *staging, + struct kdbus_conn *src, + struct kdbus_conn *dst); #endif |
