io_uring: split out fixed file installation and removal
authorJens Axboe <axboe@kernel.dk>
Mon, 13 Jun 2022 10:42:56 +0000 (04:42 -0600)
committerJens Axboe <axboe@kernel.dk>
Mon, 25 Jul 2022 00:39:16 +0000 (18:39 -0600)
Put it with the filetable code, which is where it belongs. While doing
so, have the helpers take a ctx rather than an io_kiocb. It doesn't make
sense to use a request, as it's not an operation on the request itself.
It applies to the ring itself.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/filetable.c
io_uring/filetable.h
io_uring/openclose.c
io_uring/openclose.h
io_uring/rsrc.c

index 534e1a3..abaa5ba 100644 (file)
@@ -58,11 +58,10 @@ void io_free_file_tables(struct io_file_table *table)
        table->bitmap = NULL;
 }
 
-static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
-                                unsigned int issue_flags, u32 slot_index)
+static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+                                u32 slot_index)
        __must_hold(&req->ctx->uring_lock)
 {
-       struct io_ring_ctx *ctx = req->ctx;
        bool needs_switch = false;
        struct io_fixed_file *file_slot;
        int ret;
@@ -108,34 +107,71 @@ err:
        return ret;
 }
 
-/*
- * Note when io_fixed_fd_install() returns error value, it will ensure
- * fput() is called correspondingly.
- */
-int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
-                       struct file *file, unsigned int file_slot)
+int __io_fixed_fd_install(struct io_ring_ctx *ctx, struct file *file,
+                         unsigned int file_slot)
 {
        bool alloc_slot = file_slot == IORING_FILE_INDEX_ALLOC;
-       struct io_ring_ctx *ctx = req->ctx;
        int ret;
 
-       io_ring_submit_lock(ctx, issue_flags);
-
        if (alloc_slot) {
                ret = io_file_bitmap_get(ctx);
                if (unlikely(ret < 0))
-                       goto err;
+                       return ret;
                file_slot = ret;
        } else {
                file_slot--;
        }
 
-       ret = io_install_fixed_file(req, file, issue_flags, file_slot);
+       ret = io_install_fixed_file(ctx, file, file_slot);
        if (!ret && alloc_slot)
                ret = file_slot;
-err:
+       return ret;
+}
+/*
+ * Note when io_fixed_fd_install() returns error value, it will ensure
+ * fput() is called correspondingly.
+ */
+int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
+                       struct file *file, unsigned int file_slot)
+{
+       struct io_ring_ctx *ctx = req->ctx;
+       int ret;
+
+       io_ring_submit_lock(ctx, issue_flags);
+       ret = __io_fixed_fd_install(ctx, file, file_slot);
        io_ring_submit_unlock(ctx, issue_flags);
+
        if (unlikely(ret < 0))
                fput(file);
        return ret;
 }
+
+int io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset)
+{
+       struct io_fixed_file *file_slot;
+       struct file *file;
+       int ret;
+
+       if (unlikely(!ctx->file_data))
+               return -ENXIO;
+       if (offset >= ctx->nr_user_files)
+               return -EINVAL;
+       ret = io_rsrc_node_switch_start(ctx);
+       if (ret)
+               return ret;
+
+       offset = array_index_nospec(offset, ctx->nr_user_files);
+       file_slot = io_fixed_file_slot(&ctx->file_table, offset);
+       if (!file_slot->file_ptr)
+               return -EBADF;
+
+       file = (struct file *)(file_slot->file_ptr & FFS_MASK);
+       ret = io_queue_rsrc_removal(ctx->file_data, offset, ctx->rsrc_node, file);
+       if (ret)
+               return ret;
+
+       file_slot->file_ptr = 0;
+       io_file_bitmap_clear(&ctx->file_table, offset);
+       io_rsrc_node_switch(ctx, ctx->file_data);
+       return 0;
+}
index fb5a274..79eb50c 100644 (file)
@@ -29,6 +29,9 @@ void io_free_file_tables(struct io_file_table *table);
 
 int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
                        struct file *file, unsigned int file_slot);
+int __io_fixed_fd_install(struct io_ring_ctx *ctx, struct file *file,
+                               unsigned int file_slot);
+int io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset);
 
 unsigned int io_file_get_flags(struct file *file);
 
index 099a5ec..d1818ec 100644 (file)
@@ -173,42 +173,15 @@ void io_open_cleanup(struct io_kiocb *req)
                putname(open->filename);
 }
 
-int __io_close_fixed(struct io_kiocb *req, unsigned int issue_flags,
+int __io_close_fixed(struct io_ring_ctx *ctx, unsigned int issue_flags,
                     unsigned int offset)
 {
-       struct io_ring_ctx *ctx = req->ctx;
-       struct io_fixed_file *file_slot;
-       struct file *file;
        int ret;
 
        io_ring_submit_lock(ctx, issue_flags);
-       ret = -ENXIO;
-       if (unlikely(!ctx->file_data))
-               goto out;
-       ret = -EINVAL;
-       if (offset >= ctx->nr_user_files)
-               goto out;
-       ret = io_rsrc_node_switch_start(ctx);
-       if (ret)
-               goto out;
-
-       offset = array_index_nospec(offset, ctx->nr_user_files);
-       file_slot = io_fixed_file_slot(&ctx->file_table, offset);
-       ret = -EBADF;
-       if (!file_slot->file_ptr)
-               goto out;
-
-       file = (struct file *)(file_slot->file_ptr & FFS_MASK);
-       ret = io_queue_rsrc_removal(ctx->file_data, offset, ctx->rsrc_node, file);
-       if (ret)
-               goto out;
-
-       file_slot->file_ptr = 0;
-       io_file_bitmap_clear(&ctx->file_table, offset);
-       io_rsrc_node_switch(ctx, ctx->file_data);
-       ret = 0;
-out:
+       ret = io_fixed_fd_remove(ctx, offset);
        io_ring_submit_unlock(ctx, issue_flags);
+
        return ret;
 }
 
@@ -216,7 +189,7 @@ static inline int io_close_fixed(struct io_kiocb *req, unsigned int issue_flags)
 {
        struct io_close *close = io_kiocb_to_cmd(req);
 
-       return __io_close_fixed(req, issue_flags, close->file_slot - 1);
+       return __io_close_fixed(req->ctx, issue_flags, close->file_slot - 1);
 }
 
 int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
index 9f578f3..4b1c28d 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 
-int __io_close_fixed(struct io_kiocb *req, unsigned int issue_flags,
+int __io_close_fixed(struct io_ring_ctx *ctx, unsigned int issue_flags,
                     unsigned int offset);
 
 int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
index 1106089..706fa02 100644 (file)
@@ -703,7 +703,7 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req,
                if (ret < 0)
                        break;
                if (copy_to_user(&fds[done], &ret, sizeof(ret))) {
-                       __io_close_fixed(req, issue_flags, ret);
+                       __io_close_fixed(req->ctx, issue_flags, ret);
                        ret = -EFAULT;
                        break;
                }