Loading io_uring/filetable.c +86 −1 Original line number Diff line number Diff line Loading @@ -4,14 +4,17 @@ #include <linux/file.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/nospec.h> #include <linux/io_uring.h> #include <uapi/linux/io_uring.h> #include "io_uring_types.h" #include "io_uring.h" #include "rsrc.h" #include "filetable.h" int io_file_bitmap_get(struct io_ring_ctx *ctx) static int io_file_bitmap_get(struct io_ring_ctx *ctx) { struct io_file_table *table = &ctx->file_table; unsigned long nr = ctx->nr_user_files; Loading Loading @@ -55,3 +58,85 @@ void io_free_file_tables(struct io_file_table *table) table->files = NULL; table->bitmap = NULL; } static int io_install_fixed_file(struct io_kiocb *req, struct file *file, unsigned int issue_flags, 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; if (io_is_uring_fops(file)) return -EBADF; if (!ctx->file_data) return -ENXIO; if (slot_index >= ctx->nr_user_files) return -EINVAL; slot_index = array_index_nospec(slot_index, ctx->nr_user_files); file_slot = io_fixed_file_slot(&ctx->file_table, slot_index); if (file_slot->file_ptr) { struct file *old_file; ret = io_rsrc_node_switch_start(ctx); if (ret) goto err; old_file = (struct file *)(file_slot->file_ptr & FFS_MASK); ret = io_queue_rsrc_removal(ctx->file_data, slot_index, ctx->rsrc_node, old_file); if (ret) goto err; file_slot->file_ptr = 0; io_file_bitmap_clear(&ctx->file_table, slot_index); needs_switch = true; } ret = io_scm_file_account(ctx, file); if (!ret) { *io_get_tag_slot(ctx->file_data, slot_index) = 0; io_fixed_file_set(file_slot, file); io_file_bitmap_set(&ctx->file_table, slot_index); } err: if (needs_switch) io_rsrc_node_switch(ctx, ctx->file_data); if (ret) fput(file); 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) { 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; file_slot = ret; } else { file_slot--; } ret = io_install_fixed_file(req, file, issue_flags, file_slot); if (!ret && alloc_slot) ret = file_slot; err: io_ring_submit_unlock(ctx, issue_flags); if (unlikely(ret < 0)) fput(file); return ret; } io_uring/filetable.h +4 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #define IOU_FILE_TABLE_H struct io_ring_ctx; struct io_kiocb; /* * FFS_SCM is only available on 64-bit archs, for 32-bit we just define it as 0 Loading Loading @@ -34,7 +35,9 @@ struct io_file_table { bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files); void io_free_file_tables(struct io_file_table *table); int io_file_bitmap_get(struct io_ring_ctx *ctx); int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, struct file *file, unsigned int file_slot); unsigned int io_file_get_flags(struct file *file); Loading io_uring/io_uring.c +0 −82 Original line number Diff line number Diff line Loading @@ -2699,38 +2699,6 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) 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) { 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; file_slot = ret; } else { file_slot--; } ret = io_install_fixed_file(req, file, issue_flags, file_slot); if (!ret && alloc_slot) ret = file_slot; err: io_ring_submit_unlock(ctx, issue_flags); if (unlikely(ret < 0)) fput(file); return ret; } static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb, const struct io_uring_sqe *sqe) { Loading Loading @@ -3579,56 +3547,6 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, return READ_ONCE(rings->cq.head) == READ_ONCE(rings->cq.tail) ? ret : 0; } int io_install_fixed_file(struct io_kiocb *req, struct file *file, unsigned int issue_flags, 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; if (io_is_uring_fops(file)) return -EBADF; if (!ctx->file_data) return -ENXIO; if (slot_index >= ctx->nr_user_files) return -EINVAL; slot_index = array_index_nospec(slot_index, ctx->nr_user_files); file_slot = io_fixed_file_slot(&ctx->file_table, slot_index); if (file_slot->file_ptr) { struct file *old_file; ret = io_rsrc_node_switch_start(ctx); if (ret) goto err; old_file = (struct file *)(file_slot->file_ptr & FFS_MASK); ret = io_queue_rsrc_removal(ctx->file_data, slot_index, ctx->rsrc_node, old_file); if (ret) goto err; file_slot->file_ptr = 0; io_file_bitmap_clear(&ctx->file_table, slot_index); needs_switch = true; } ret = io_scm_file_account(ctx, file); if (!ret) { *io_get_tag_slot(ctx->file_data, slot_index) = 0; io_fixed_file_set(file_slot, file); io_file_bitmap_set(&ctx->file_table, slot_index); } err: if (needs_switch) io_rsrc_node_switch(ctx, ctx->file_data); if (ret) fput(file); return ret; } static void io_mem_free(void *ptr) { struct page *page; Loading io_uring/io_uring.h +0 −4 Original line number Diff line number Diff line Loading @@ -106,10 +106,6 @@ struct page **io_pin_pages(unsigned long ubuf, unsigned long len, int *npages); 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); int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, struct file *file, unsigned int file_slot); int io_install_fixed_file(struct io_kiocb *req, struct file *file, unsigned int issue_flags, u32 slot_index); bool io_is_uring_fops(struct file *file); bool io_alloc_async_data(struct io_kiocb *req); Loading Loading
io_uring/filetable.c +86 −1 Original line number Diff line number Diff line Loading @@ -4,14 +4,17 @@ #include <linux/file.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/nospec.h> #include <linux/io_uring.h> #include <uapi/linux/io_uring.h> #include "io_uring_types.h" #include "io_uring.h" #include "rsrc.h" #include "filetable.h" int io_file_bitmap_get(struct io_ring_ctx *ctx) static int io_file_bitmap_get(struct io_ring_ctx *ctx) { struct io_file_table *table = &ctx->file_table; unsigned long nr = ctx->nr_user_files; Loading Loading @@ -55,3 +58,85 @@ void io_free_file_tables(struct io_file_table *table) table->files = NULL; table->bitmap = NULL; } static int io_install_fixed_file(struct io_kiocb *req, struct file *file, unsigned int issue_flags, 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; if (io_is_uring_fops(file)) return -EBADF; if (!ctx->file_data) return -ENXIO; if (slot_index >= ctx->nr_user_files) return -EINVAL; slot_index = array_index_nospec(slot_index, ctx->nr_user_files); file_slot = io_fixed_file_slot(&ctx->file_table, slot_index); if (file_slot->file_ptr) { struct file *old_file; ret = io_rsrc_node_switch_start(ctx); if (ret) goto err; old_file = (struct file *)(file_slot->file_ptr & FFS_MASK); ret = io_queue_rsrc_removal(ctx->file_data, slot_index, ctx->rsrc_node, old_file); if (ret) goto err; file_slot->file_ptr = 0; io_file_bitmap_clear(&ctx->file_table, slot_index); needs_switch = true; } ret = io_scm_file_account(ctx, file); if (!ret) { *io_get_tag_slot(ctx->file_data, slot_index) = 0; io_fixed_file_set(file_slot, file); io_file_bitmap_set(&ctx->file_table, slot_index); } err: if (needs_switch) io_rsrc_node_switch(ctx, ctx->file_data); if (ret) fput(file); 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) { 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; file_slot = ret; } else { file_slot--; } ret = io_install_fixed_file(req, file, issue_flags, file_slot); if (!ret && alloc_slot) ret = file_slot; err: io_ring_submit_unlock(ctx, issue_flags); if (unlikely(ret < 0)) fput(file); return ret; }
io_uring/filetable.h +4 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #define IOU_FILE_TABLE_H struct io_ring_ctx; struct io_kiocb; /* * FFS_SCM is only available on 64-bit archs, for 32-bit we just define it as 0 Loading Loading @@ -34,7 +35,9 @@ struct io_file_table { bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files); void io_free_file_tables(struct io_file_table *table); int io_file_bitmap_get(struct io_ring_ctx *ctx); int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, struct file *file, unsigned int file_slot); unsigned int io_file_get_flags(struct file *file); Loading
io_uring/io_uring.c +0 −82 Original line number Diff line number Diff line Loading @@ -2699,38 +2699,6 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) 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) { 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; file_slot = ret; } else { file_slot--; } ret = io_install_fixed_file(req, file, issue_flags, file_slot); if (!ret && alloc_slot) ret = file_slot; err: io_ring_submit_unlock(ctx, issue_flags); if (unlikely(ret < 0)) fput(file); return ret; } static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb, const struct io_uring_sqe *sqe) { Loading Loading @@ -3579,56 +3547,6 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, return READ_ONCE(rings->cq.head) == READ_ONCE(rings->cq.tail) ? ret : 0; } int io_install_fixed_file(struct io_kiocb *req, struct file *file, unsigned int issue_flags, 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; if (io_is_uring_fops(file)) return -EBADF; if (!ctx->file_data) return -ENXIO; if (slot_index >= ctx->nr_user_files) return -EINVAL; slot_index = array_index_nospec(slot_index, ctx->nr_user_files); file_slot = io_fixed_file_slot(&ctx->file_table, slot_index); if (file_slot->file_ptr) { struct file *old_file; ret = io_rsrc_node_switch_start(ctx); if (ret) goto err; old_file = (struct file *)(file_slot->file_ptr & FFS_MASK); ret = io_queue_rsrc_removal(ctx->file_data, slot_index, ctx->rsrc_node, old_file); if (ret) goto err; file_slot->file_ptr = 0; io_file_bitmap_clear(&ctx->file_table, slot_index); needs_switch = true; } ret = io_scm_file_account(ctx, file); if (!ret) { *io_get_tag_slot(ctx->file_data, slot_index) = 0; io_fixed_file_set(file_slot, file); io_file_bitmap_set(&ctx->file_table, slot_index); } err: if (needs_switch) io_rsrc_node_switch(ctx, ctx->file_data); if (ret) fput(file); return ret; } static void io_mem_free(void *ptr) { struct page *page; Loading
io_uring/io_uring.h +0 −4 Original line number Diff line number Diff line Loading @@ -106,10 +106,6 @@ struct page **io_pin_pages(unsigned long ubuf, unsigned long len, int *npages); 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); int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags, struct file *file, unsigned int file_slot); int io_install_fixed_file(struct io_kiocb *req, struct file *file, unsigned int issue_flags, u32 slot_index); bool io_is_uring_fops(struct file *file); bool io_alloc_async_data(struct io_kiocb *req); Loading