1 /* SPDX-License-Identifier: MIT */
2 #define _POSIX_C_SOURCE 200112L
3
4 #include "lib.h"
5 #include "syscall.h"
6 #include "liburing.h"
7 #include "int_flags.h"
8 #include "liburing/compat.h"
9 #include "liburing/io_uring.h"
10
io_uring_register_buffers_update_tag(struct io_uring * ring,unsigned off,const struct iovec * iovecs,const __u64 * tags,unsigned nr)11 int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off,
12 const struct iovec *iovecs,
13 const __u64 *tags,
14 unsigned nr)
15 {
16 struct io_uring_rsrc_update2 up = {
17 .offset = off,
18 .data = (unsigned long)iovecs,
19 .tags = (unsigned long)tags,
20 .nr = nr,
21 };
22
23 return ____sys_io_uring_register(ring->ring_fd,
24 IORING_REGISTER_BUFFERS_UPDATE, &up,
25 sizeof(up));
26 }
27
io_uring_register_buffers_tags(struct io_uring * ring,const struct iovec * iovecs,const __u64 * tags,unsigned nr)28 int io_uring_register_buffers_tags(struct io_uring *ring,
29 const struct iovec *iovecs,
30 const __u64 *tags,
31 unsigned nr)
32 {
33 struct io_uring_rsrc_register reg = {
34 .nr = nr,
35 .data = (unsigned long)iovecs,
36 .tags = (unsigned long)tags,
37 };
38
39 return ____sys_io_uring_register(ring->ring_fd,
40 IORING_REGISTER_BUFFERS2, ®,
41 sizeof(reg));
42 }
43
io_uring_register_buffers_sparse(struct io_uring * ring,unsigned nr)44 int io_uring_register_buffers_sparse(struct io_uring *ring, unsigned nr)
45 {
46 struct io_uring_rsrc_register reg = {
47 .flags = IORING_RSRC_REGISTER_SPARSE,
48 .nr = nr,
49 };
50
51 return ____sys_io_uring_register(ring->ring_fd,
52 IORING_REGISTER_BUFFERS2, ®,
53 sizeof(reg));
54 }
55
io_uring_register_buffers(struct io_uring * ring,const struct iovec * iovecs,unsigned nr_iovecs)56 int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs,
57 unsigned nr_iovecs)
58 {
59 int ret;
60
61 ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_BUFFERS,
62 iovecs, nr_iovecs);
63 return (ret < 0) ? ret : 0;
64 }
65
io_uring_unregister_buffers(struct io_uring * ring)66 int io_uring_unregister_buffers(struct io_uring *ring)
67 {
68 int ret;
69
70 ret = ____sys_io_uring_register(ring->ring_fd,
71 IORING_UNREGISTER_BUFFERS, NULL, 0);
72 return (ret < 0) ? ret : 0;
73 }
74
io_uring_register_files_update_tag(struct io_uring * ring,unsigned off,const int * files,const __u64 * tags,unsigned nr_files)75 int io_uring_register_files_update_tag(struct io_uring *ring, unsigned off,
76 const int *files, const __u64 *tags,
77 unsigned nr_files)
78 {
79 struct io_uring_rsrc_update2 up = {
80 .offset = off,
81 .data = (unsigned long)files,
82 .tags = (unsigned long)tags,
83 .nr = nr_files,
84 };
85
86 return ____sys_io_uring_register(ring->ring_fd,
87 IORING_REGISTER_FILES_UPDATE2, &up,
88 sizeof(up));
89 }
90
91 /*
92 * Register an update for an existing file set. The updates will start at
93 * 'off' in the original array, and 'nr_files' is the number of files we'll
94 * update.
95 *
96 * Returns number of files updated on success, -ERROR on failure.
97 */
io_uring_register_files_update(struct io_uring * ring,unsigned off,int * files,unsigned nr_files)98 int io_uring_register_files_update(struct io_uring *ring, unsigned off,
99 int *files, unsigned nr_files)
100 {
101 struct io_uring_files_update up = {
102 .offset = off,
103 .fds = (unsigned long) files,
104 };
105
106 return ____sys_io_uring_register(ring->ring_fd,
107 IORING_REGISTER_FILES_UPDATE, &up,
108 nr_files);
109 }
110
increase_rlimit_nofile(unsigned nr)111 static int increase_rlimit_nofile(unsigned nr)
112 {
113 int ret;
114 struct rlimit rlim;
115
116 ret = __sys_getrlimit(RLIMIT_NOFILE, &rlim);
117 if (ret < 0)
118 return ret;
119
120 if (rlim.rlim_cur < nr) {
121 rlim.rlim_cur += nr;
122 __sys_setrlimit(RLIMIT_NOFILE, &rlim);
123 }
124
125 return 0;
126 }
127
io_uring_register_files_sparse(struct io_uring * ring,unsigned nr)128 int io_uring_register_files_sparse(struct io_uring *ring, unsigned nr)
129 {
130 struct io_uring_rsrc_register reg = {
131 .flags = IORING_RSRC_REGISTER_SPARSE,
132 .nr = nr,
133 };
134 int ret, did_increase = 0;
135
136 do {
137 ret = ____sys_io_uring_register(ring->ring_fd,
138 IORING_REGISTER_FILES2, ®,
139 sizeof(reg));
140 if (ret >= 0)
141 break;
142 if (ret == -EMFILE && !did_increase) {
143 did_increase = 1;
144 increase_rlimit_nofile(nr);
145 continue;
146 }
147 break;
148 } while (1);
149
150 return ret;
151 }
152
io_uring_register_files_tags(struct io_uring * ring,const int * files,const __u64 * tags,unsigned nr)153 int io_uring_register_files_tags(struct io_uring *ring, const int *files,
154 const __u64 *tags, unsigned nr)
155 {
156 struct io_uring_rsrc_register reg = {
157 .nr = nr,
158 .data = (unsigned long)files,
159 .tags = (unsigned long)tags,
160 };
161 int ret, did_increase = 0;
162
163 do {
164 ret = ____sys_io_uring_register(ring->ring_fd,
165 IORING_REGISTER_FILES2, ®,
166 sizeof(reg));
167 if (ret >= 0)
168 break;
169 if (ret == -EMFILE && !did_increase) {
170 did_increase = 1;
171 increase_rlimit_nofile(nr);
172 continue;
173 }
174 break;
175 } while (1);
176
177 return ret;
178 }
179
io_uring_register_files(struct io_uring * ring,const int * files,unsigned nr_files)180 int io_uring_register_files(struct io_uring *ring, const int *files,
181 unsigned nr_files)
182 {
183 int ret, did_increase = 0;
184
185 do {
186 ret = ____sys_io_uring_register(ring->ring_fd,
187 IORING_REGISTER_FILES, files,
188 nr_files);
189 if (ret >= 0)
190 break;
191 if (ret == -EMFILE && !did_increase) {
192 did_increase = 1;
193 increase_rlimit_nofile(nr_files);
194 continue;
195 }
196 break;
197 } while (1);
198
199 return ret;
200 }
201
io_uring_unregister_files(struct io_uring * ring)202 int io_uring_unregister_files(struct io_uring *ring)
203 {
204 int ret;
205
206 ret = ____sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_FILES,
207 NULL, 0);
208 return (ret < 0) ? ret : 0;
209 }
210
io_uring_register_eventfd(struct io_uring * ring,int event_fd)211 int io_uring_register_eventfd(struct io_uring *ring, int event_fd)
212 {
213 int ret;
214
215 ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD,
216 &event_fd, 1);
217 return (ret < 0) ? ret : 0;
218 }
219
io_uring_unregister_eventfd(struct io_uring * ring)220 int io_uring_unregister_eventfd(struct io_uring *ring)
221 {
222 int ret;
223
224 ret = ____sys_io_uring_register(ring->ring_fd,
225 IORING_UNREGISTER_EVENTFD, NULL, 0);
226 return (ret < 0) ? ret : 0;
227 }
228
io_uring_register_eventfd_async(struct io_uring * ring,int event_fd)229 int io_uring_register_eventfd_async(struct io_uring *ring, int event_fd)
230 {
231 int ret;
232
233 ret = ____sys_io_uring_register(ring->ring_fd,
234 IORING_REGISTER_EVENTFD_ASYNC,
235 &event_fd, 1);
236 return (ret < 0) ? ret : 0;
237 }
238
io_uring_register_probe(struct io_uring * ring,struct io_uring_probe * p,unsigned int nr_ops)239 int io_uring_register_probe(struct io_uring *ring, struct io_uring_probe *p,
240 unsigned int nr_ops)
241 {
242 int ret;
243
244 ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PROBE, p,
245 nr_ops);
246 return (ret < 0) ? ret : 0;
247 }
248
io_uring_register_personality(struct io_uring * ring)249 int io_uring_register_personality(struct io_uring *ring)
250 {
251 return ____sys_io_uring_register(ring->ring_fd,
252 IORING_REGISTER_PERSONALITY, NULL, 0);
253 }
254
io_uring_unregister_personality(struct io_uring * ring,int id)255 int io_uring_unregister_personality(struct io_uring *ring, int id)
256 {
257 return ____sys_io_uring_register(ring->ring_fd,
258 IORING_UNREGISTER_PERSONALITY, NULL,
259 id);
260 }
261
io_uring_register_restrictions(struct io_uring * ring,struct io_uring_restriction * res,unsigned int nr_res)262 int io_uring_register_restrictions(struct io_uring *ring,
263 struct io_uring_restriction *res,
264 unsigned int nr_res)
265 {
266 int ret;
267
268 ret = ____sys_io_uring_register(ring->ring_fd,
269 IORING_REGISTER_RESTRICTIONS, res,
270 nr_res);
271 return (ret < 0) ? ret : 0;
272 }
273
io_uring_enable_rings(struct io_uring * ring)274 int io_uring_enable_rings(struct io_uring *ring)
275 {
276 return ____sys_io_uring_register(ring->ring_fd,
277 IORING_REGISTER_ENABLE_RINGS, NULL, 0);
278 }
279
io_uring_register_iowq_aff(struct io_uring * ring,size_t cpusz,const cpu_set_t * mask)280 int io_uring_register_iowq_aff(struct io_uring *ring, size_t cpusz,
281 const cpu_set_t *mask)
282 {
283 return ____sys_io_uring_register(ring->ring_fd,
284 IORING_REGISTER_IOWQ_AFF, mask, cpusz);
285 }
286
io_uring_unregister_iowq_aff(struct io_uring * ring)287 int io_uring_unregister_iowq_aff(struct io_uring *ring)
288 {
289 return ____sys_io_uring_register(ring->ring_fd,
290 IORING_UNREGISTER_IOWQ_AFF, NULL, 0);
291 }
292
io_uring_register_iowq_max_workers(struct io_uring * ring,unsigned int * val)293 int io_uring_register_iowq_max_workers(struct io_uring *ring, unsigned int *val)
294 {
295 return ____sys_io_uring_register(ring->ring_fd,
296 IORING_REGISTER_IOWQ_MAX_WORKERS, val,
297 2);
298 }
299
io_uring_register_ring_fd(struct io_uring * ring)300 int io_uring_register_ring_fd(struct io_uring *ring)
301 {
302 struct io_uring_rsrc_update up = {
303 .data = ring->ring_fd,
304 .offset = -1U,
305 };
306 int ret;
307
308 ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_RING_FDS,
309 &up, 1);
310 if (ret == 1) {
311 ring->enter_ring_fd = up.offset;
312 ring->int_flags |= INT_FLAG_REG_RING;
313 }
314 return ret;
315 }
316
317
io_uring_unregister_ring_fd(struct io_uring * ring)318 int io_uring_unregister_ring_fd(struct io_uring *ring)
319 {
320 struct io_uring_rsrc_update up = {
321 .offset = ring->enter_ring_fd,
322 };
323 int ret;
324
325 ret = ____sys_io_uring_register(ring->ring_fd,
326 IORING_UNREGISTER_RING_FDS, &up, 1);
327 if (ret == 1) {
328 ring->enter_ring_fd = ring->ring_fd;
329 ring->int_flags &= ~INT_FLAG_REG_RING;
330 }
331 return ret;
332 }
333
io_uring_register_buf_ring(struct io_uring * ring,struct io_uring_buf_reg * reg,unsigned int flags)334 int io_uring_register_buf_ring(struct io_uring *ring,
335 struct io_uring_buf_reg *reg, unsigned int flags)
336 {
337 return ____sys_io_uring_register(ring->ring_fd,
338 IORING_REGISTER_PBUF_RING, reg, 1);
339 }
340
io_uring_unregister_buf_ring(struct io_uring * ring,int bgid)341 int io_uring_unregister_buf_ring(struct io_uring *ring, int bgid)
342 {
343 struct io_uring_buf_reg reg = { .bgid = bgid };
344
345 return ____sys_io_uring_register(ring->ring_fd,
346 IORING_UNREGISTER_PBUF_RING, ®, 1);
347 }
348