]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
io_uring: unify getting ctx from passed in file descriptor
authorJens Axboe <axboe@kernel.dk>
Wed, 8 Apr 2026 17:56:02 +0000 (11:56 -0600)
committerJens Axboe <axboe@kernel.dk>
Wed, 8 Apr 2026 19:21:35 +0000 (13:21 -0600)
io_uring_enter() and io_uring_register() end up having duplicated code
for getting a ctx from a passed in file descriptor, for either a
registered ring descriptor or a normal file descriptor. Move the
io_uring_register_get_file() into io_uring.c and name it a bit more
generically, and use it from both callsites rather than have that logic
and handling duplicated.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/bpf-ops.c
io_uring/io_uring.c
io_uring/io_uring.h
io_uring/register.c
io_uring/register.h
io_uring/rsrc.c

index e4b244337aa98efeec5b5d415f5598fe1d04f214..937e48bef40bcc05f9590badd6a1dcd3929dee22 100644 (file)
@@ -181,7 +181,7 @@ static int bpf_io_reg(void *kdata, struct bpf_link *link)
        struct file *file;
        int ret = -EBUSY;
 
-       file = io_uring_register_get_file(ops->ring_fd, false);
+       file = io_uring_ctx_get_file(ops->ring_fd, false);
        if (IS_ERR(file))
                return PTR_ERR(file);
        ctx = file->private_data;
index 16122f877aedc7386f44e5c6f62a0690c66e514c..003f0e081d92e1dd1dc73887c84b3e573c0563a7 100644 (file)
@@ -2543,39 +2543,54 @@ uaccess_end:
 #endif
 }
 
-SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
-               u32, min_complete, u32, flags, const void __user *, argp,
-               size_t, argsz)
+/*
+ * Given an 'fd' value, return the ctx associated with if. If 'registered' is
+ * true, then the registered index is used. Otherwise, the normal fd table.
+ * Caller must call fput() on the returned file if it isn't a registered file,
+ * unless it's an ERR_PTR.
+ */
+struct file *io_uring_ctx_get_file(unsigned int fd, bool registered)
 {
-       struct io_ring_ctx *ctx;
        struct file *file;
-       long ret;
-
-       if (unlikely(flags & ~IORING_ENTER_FLAGS))
-               return -EINVAL;
 
-       /*
-        * Ring fd has been registered via IORING_REGISTER_RING_FDS, we
-        * need only dereference our task private array to find it.
-        */
-       if (flags & IORING_ENTER_REGISTERED_RING) {
+       if (registered) {
+               /*
+                * Ring fd has been registered via IORING_REGISTER_RING_FDS, we
+                * need only dereference our task private array to find it.
+                */
                struct io_uring_task *tctx = current->io_uring;
 
                if (unlikely(!tctx || fd >= IO_RINGFD_REG_MAX))
-                       return -EINVAL;
+                       return ERR_PTR(-EINVAL);
                fd = array_index_nospec(fd, IO_RINGFD_REG_MAX);
                file = tctx->registered_rings[fd];
-               if (unlikely(!file))
-                       return -EBADF;
        } else {
                file = fget(fd);
-               if (unlikely(!file))
-                       return -EBADF;
-               ret = -EOPNOTSUPP;
-               if (unlikely(!io_is_uring_fops(file)))
-                       goto out;
        }
 
+       if (unlikely(!file))
+               return ERR_PTR(-EBADF);
+       if (io_is_uring_fops(file))
+               return file;
+       fput(file);
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
+
+SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
+               u32, min_complete, u32, flags, const void __user *, argp,
+               size_t, argsz)
+{
+       struct io_ring_ctx *ctx;
+       struct file *file;
+       long ret;
+
+       if (unlikely(flags & ~IORING_ENTER_FLAGS))
+               return -EINVAL;
+
+       file = io_uring_ctx_get_file(fd, flags & IORING_ENTER_REGISTERED_RING);
+       if (IS_ERR(file))
+               return PTR_ERR(file);
        ctx = file->private_data;
        ret = -EBADFD;
        /*
index 91cf67b5d85bc846856886f380608152363b1b07..e43995682c8b70c2ef11312fa7220184cc4170f4 100644 (file)
@@ -173,6 +173,7 @@ void io_req_track_inflight(struct io_kiocb *req);
 struct file *io_file_get_normal(struct io_kiocb *req, int fd);
 struct file *io_file_get_fixed(struct io_kiocb *req, int fd,
                               unsigned issue_flags);
+struct file *io_uring_ctx_get_file(unsigned int fd, bool registered);
 
 void io_req_task_queue(struct io_kiocb *req);
 void io_req_task_complete(struct io_tw_req tw_req, io_tw_token_t tw);
index 95cfa88dc621f4bcdac9393038a38957e0abe789..6260196929a7fe518c1665c479ae5527e59c55d4 100644 (file)
@@ -938,39 +938,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
        return ret;
 }
 
-/*
- * Given an 'fd' value, return the ctx associated with if. If 'registered' is
- * true, then the registered index is used. Otherwise, the normal fd table.
- * Caller must call fput() on the returned file if it isn't a registered file,
- * unless it's an ERR_PTR.
- */
-struct file *io_uring_register_get_file(unsigned int fd, bool registered)
-{
-       struct file *file;
-
-       if (registered) {
-               /*
-                * Ring fd has been registered via IORING_REGISTER_RING_FDS, we
-                * need only dereference our task private array to find it.
-                */
-               struct io_uring_task *tctx = current->io_uring;
-
-               if (unlikely(!tctx || fd >= IO_RINGFD_REG_MAX))
-                       return ERR_PTR(-EINVAL);
-               fd = array_index_nospec(fd, IO_RINGFD_REG_MAX);
-               file = tctx->registered_rings[fd];
-       } else {
-               file = fget(fd);
-       }
-
-       if (unlikely(!file))
-               return ERR_PTR(-EBADF);
-       if (io_is_uring_fops(file))
-               return file;
-       fput(file);
-       return ERR_PTR(-EOPNOTSUPP);
-}
-
 static int io_uring_register_send_msg_ring(void __user *arg, unsigned int nr_args)
 {
        struct io_uring_sqe sqe;
@@ -1025,7 +992,7 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
        if (fd == -1)
                return io_uring_register_blind(opcode, arg, nr_args);
 
-       file = io_uring_register_get_file(fd, use_registered_ring);
+       file = io_uring_ctx_get_file(fd, use_registered_ring);
        if (IS_ERR(file))
                return PTR_ERR(file);
        ctx = file->private_data;
index a5f39d5ef9e0e4588134c6b50ae4905430f8e1d1..c9da997d503c127a682a0829a69f4a1bc8a24956 100644 (file)
@@ -4,6 +4,5 @@
 
 int io_eventfd_unregister(struct io_ring_ctx *ctx);
 int io_unregister_personality(struct io_ring_ctx *ctx, unsigned id);
-struct file *io_uring_register_get_file(unsigned int fd, bool registered);
 
 #endif
index cb12194b35e8f1626893a4976019bc54c82f3adc..57151c01da0f1efbe0b8a2ffbcddc42e4cae7526 100644 (file)
@@ -1269,7 +1269,7 @@ int io_register_clone_buffers(struct io_ring_ctx *ctx, void __user *arg)
                return -EINVAL;
 
        registered_src = (buf.flags & IORING_REGISTER_SRC_REGISTERED) != 0;
-       file = io_uring_register_get_file(buf.src_fd, registered_src);
+       file = io_uring_ctx_get_file(buf.src_fd, registered_src);
        if (IS_ERR(file))
                return PTR_ERR(file);