diff options
Diffstat (limited to 'src/register.c')
-rw-r--r-- | src/register.c | 328 |
1 files changed, 243 insertions, 85 deletions
diff --git a/src/register.c b/src/register.c index 994aaff..993c450 100644 --- a/src/register.c +++ b/src/register.c @@ -1,42 +1,91 @@ /* SPDX-License-Identifier: MIT */ #define _POSIX_C_SOURCE 200112L -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - +#include "lib.h" +#include "syscall.h" +#include "liburing.h" +#include "int_flags.h" #include "liburing/compat.h" #include "liburing/io_uring.h" -#include "liburing.h" -#include "syscall.h" +int io_uring_register_buffers_update_tag(struct io_uring *ring, unsigned off, + const struct iovec *iovecs, + const __u64 *tags, + unsigned nr) +{ + struct io_uring_rsrc_update2 up = { + .offset = off, + .data = (unsigned long)iovecs, + .tags = (unsigned long)tags, + .nr = nr, + }; + + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_BUFFERS_UPDATE, &up, + sizeof(up)); +} + +int io_uring_register_buffers_tags(struct io_uring *ring, + const struct iovec *iovecs, + const __u64 *tags, + unsigned nr) +{ + struct io_uring_rsrc_register reg = { + .nr = nr, + .data = (unsigned long)iovecs, + .tags = (unsigned long)tags, + }; + + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_BUFFERS2, ®, + sizeof(reg)); +} + +int io_uring_register_buffers_sparse(struct io_uring *ring, unsigned nr) +{ + struct io_uring_rsrc_register reg = { + .flags = IORING_RSRC_REGISTER_SPARSE, + .nr = nr, + }; + + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_BUFFERS2, ®, + sizeof(reg)); +} int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs, unsigned nr_iovecs) { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_BUFFERS, + ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_BUFFERS, iovecs, nr_iovecs); - if (ret < 0) - return -errno; - - return 0; + return (ret < 0) ? ret : 0; } int io_uring_unregister_buffers(struct io_uring *ring) { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_BUFFERS, - NULL, 0); - if (ret < 0) - return -errno; + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_UNREGISTER_BUFFERS, NULL, 0); + return (ret < 0) ? ret : 0; +} - return 0; +int io_uring_register_files_update_tag(struct io_uring *ring, unsigned off, + const int *files, const __u64 *tags, + unsigned nr_files) +{ + struct io_uring_rsrc_update2 up = { + .offset = off, + .data = (unsigned long)files, + .tags = (unsigned long)tags, + .nr = nr_files, + }; + + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_FILES_UPDATE2, &up, + sizeof(up)); } /* @@ -53,76 +102,138 @@ int io_uring_register_files_update(struct io_uring *ring, unsigned off, .offset = off, .fds = (unsigned long) files, }; + + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_FILES_UPDATE, &up, + nr_files); +} + +static int increase_rlimit_nofile(unsigned nr) +{ int ret; + struct rlimit rlim; - ret = __sys_io_uring_register(ring->ring_fd, - IORING_REGISTER_FILES_UPDATE, &up, - nr_files); + ret = __sys_getrlimit(RLIMIT_NOFILE, &rlim); if (ret < 0) - return -errno; + return ret; + + if (rlim.rlim_cur < nr) { + rlim.rlim_cur += nr; + __sys_setrlimit(RLIMIT_NOFILE, &rlim); + } + + return 0; +} + +int io_uring_register_files_sparse(struct io_uring *ring, unsigned nr) +{ + struct io_uring_rsrc_register reg = { + .flags = IORING_RSRC_REGISTER_SPARSE, + .nr = nr, + }; + int ret, did_increase = 0; + + do { + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_FILES2, ®, + sizeof(reg)); + if (ret >= 0) + break; + if (ret == -EMFILE && !did_increase) { + did_increase = 1; + increase_rlimit_nofile(nr); + continue; + } + break; + } while (1); return ret; } -int io_uring_register_files(struct io_uring *ring, const int *files, - unsigned nr_files) +int io_uring_register_files_tags(struct io_uring *ring, const int *files, + const __u64 *tags, unsigned nr) { - int ret; + struct io_uring_rsrc_register reg = { + .nr = nr, + .data = (unsigned long)files, + .tags = (unsigned long)tags, + }; + int ret, did_increase = 0; + + do { + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_FILES2, ®, + sizeof(reg)); + if (ret >= 0) + break; + if (ret == -EMFILE && !did_increase) { + did_increase = 1; + increase_rlimit_nofile(nr); + continue; + } + break; + } while (1); - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_FILES, - files, nr_files); - if (ret < 0) - return -errno; + return ret; +} - return 0; +int io_uring_register_files(struct io_uring *ring, const int *files, + unsigned nr_files) +{ + int ret, did_increase = 0; + + do { + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_FILES, files, + nr_files); + if (ret >= 0) + break; + if (ret == -EMFILE && !did_increase) { + did_increase = 1; + increase_rlimit_nofile(nr_files); + continue; + } + break; + } while (1); + + return ret; } int io_uring_unregister_files(struct io_uring *ring) { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_FILES, + ret = ____sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_FILES, NULL, 0); - if (ret < 0) - return -errno; - - return 0; + return (ret < 0) ? ret : 0; } int io_uring_register_eventfd(struct io_uring *ring, int event_fd) { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD, + ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD, &event_fd, 1); - if (ret < 0) - return -errno; - - return 0; + return (ret < 0) ? ret : 0; } int io_uring_unregister_eventfd(struct io_uring *ring) { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_EVENTFD, - NULL, 0); - if (ret < 0) - return -errno; - - return 0; + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_UNREGISTER_EVENTFD, NULL, 0); + return (ret < 0) ? ret : 0; } int io_uring_register_eventfd_async(struct io_uring *ring, int event_fd) { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD_ASYNC, - &event_fd, 1); - if (ret < 0) - return -errno; - - return 0; + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_EVENTFD_ASYNC, + &event_fd, 1); + return (ret < 0) ? ret : 0; } int io_uring_register_probe(struct io_uring *ring, struct io_uring_probe *p, @@ -130,36 +241,22 @@ int io_uring_register_probe(struct io_uring *ring, struct io_uring_probe *p, { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PROBE, - p, nr_ops); - if (ret < 0) - return -errno; - - return 0; + ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PROBE, p, + nr_ops); + return (ret < 0) ? ret : 0; } int io_uring_register_personality(struct io_uring *ring) { - int ret; - - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PERSONALITY, - NULL, 0); - if (ret < 0) - return -errno; - - return ret; + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_PERSONALITY, NULL, 0); } int io_uring_unregister_personality(struct io_uring *ring, int id) { - int ret; - - ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_PERSONALITY, - NULL, id); - if (ret < 0) - return -errno; - - return ret; + return ____sys_io_uring_register(ring->ring_fd, + IORING_UNREGISTER_PERSONALITY, NULL, + id); } int io_uring_register_restrictions(struct io_uring *ring, @@ -168,22 +265,83 @@ int io_uring_register_restrictions(struct io_uring *ring, { int ret; - ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_RESTRICTIONS, - res, nr_res); - if (ret < 0) - return -errno; - - return 0; + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_RESTRICTIONS, res, + nr_res); + return (ret < 0) ? ret : 0; } int io_uring_enable_rings(struct io_uring *ring) { + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_ENABLE_RINGS, NULL, 0); +} + +int io_uring_register_iowq_aff(struct io_uring *ring, size_t cpusz, + const cpu_set_t *mask) +{ + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_IOWQ_AFF, mask, cpusz); +} + +int io_uring_unregister_iowq_aff(struct io_uring *ring) +{ + return ____sys_io_uring_register(ring->ring_fd, + IORING_UNREGISTER_IOWQ_AFF, NULL, 0); +} + +int io_uring_register_iowq_max_workers(struct io_uring *ring, unsigned int *val) +{ + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_IOWQ_MAX_WORKERS, val, + 2); +} + +int io_uring_register_ring_fd(struct io_uring *ring) +{ + struct io_uring_rsrc_update up = { + .data = ring->ring_fd, + .offset = -1U, + }; int ret; - ret = __sys_io_uring_register(ring->ring_fd, - IORING_REGISTER_ENABLE_RINGS, NULL, 0); - if (ret < 0) - return -errno; + ret = ____sys_io_uring_register(ring->ring_fd, IORING_REGISTER_RING_FDS, + &up, 1); + if (ret == 1) { + ring->enter_ring_fd = up.offset; + ring->int_flags |= INT_FLAG_REG_RING; + } + return ret; +} + + +int io_uring_unregister_ring_fd(struct io_uring *ring) +{ + struct io_uring_rsrc_update up = { + .offset = ring->enter_ring_fd, + }; + int ret; + ret = ____sys_io_uring_register(ring->ring_fd, + IORING_UNREGISTER_RING_FDS, &up, 1); + if (ret == 1) { + ring->enter_ring_fd = ring->ring_fd; + ring->int_flags &= ~INT_FLAG_REG_RING; + } return ret; } + +int io_uring_register_buf_ring(struct io_uring *ring, + struct io_uring_buf_reg *reg, unsigned int flags) +{ + return ____sys_io_uring_register(ring->ring_fd, + IORING_REGISTER_PBUF_RING, reg, 1); +} + +int io_uring_unregister_buf_ring(struct io_uring *ring, int bgid) +{ + struct io_uring_buf_reg reg = { .bgid = bgid }; + + return ____sys_io_uring_register(ring->ring_fd, + IORING_UNREGISTER_PBUF_RING, ®, 1); +} |