xref: /aosp_15_r20/external/liburing/src/register.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
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, &reg,
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, &reg,
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, &reg,
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, &reg,
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, &reg, 1);
347 }
348