1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/*
* Copyright (C) 2013-2015 Kay Sievers
* Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
* Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
* Copyright (C) 2013-2015 Linux Foundation
*
* kdbus is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*/
#ifndef __KDBUS_MESSAGE_H
#define __KDBUS_MESSAGE_H
#include <linux/fs.h>
#include <linux/kref.h>
#include <uapi/linux/kdbus.h>
struct kdbus_bus;
struct kdbus_conn;
struct kdbus_meta_conn;
struct kdbus_meta_proc;
struct kdbus_pool_slice;
/**
* struct kdbus_gaps - gaps in message to be filled later
* @kref: Reference counter
* @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_gaps {
struct kref kref;
/* state tracking for KDBUS_ITEM_PAYLOAD_MEMFD entries */
size_t n_memfds;
u64 *memfd_offsets;
struct file **memfd_files;
/* state tracking for KDBUS_ITEM_FDS */
size_t n_fds;
struct file **fd_files;
u64 fd_offset;
};
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_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_staging {
struct kdbus_msg *msg;
struct kdbus_gaps *gaps;
u64 msg_seqnum;
struct list_head notify_entry;
/* crafted iovecs to copy the message */
size_t i_payload;
size_t n_payload;
size_t n_parts;
struct iovec *parts;
/* metadata state */
struct kdbus_meta_proc *meta_proc;
struct kdbus_meta_conn *meta_conn;
/* cached pointers into @msg */
const struct kdbus_bloom_filter *bloom_filter;
const char *dst_name;
struct kdbus_item *notify;
};
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
|