io_uring/rsrc: get rid of the empty node and dummy_ubuf
authorJens Axboe <axboe@kernel.dk>
Wed, 30 Oct 2024 15:51:58 +0000 (09:51 -0600)
committerJens Axboe <axboe@kernel.dk>
Sat, 2 Nov 2024 21:45:30 +0000 (15:45 -0600)
The empty node was used as a placeholder for a sparse entry, but it
didn't really solve any issues. The caller still has to check for
whether it's the empty node or not, it may as well just check for a NULL
return instead.

The dummy_ubuf was used for a sparse buffer entry, but NULL will serve
the same purpose there of ensuring an -EFAULT on attempted import.

Just use NULL for a sparse node, regardless of whether or not it's a
file or buffer resource.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/fdinfo.c
io_uring/io_uring.c
io_uring/notif.c
io_uring/rsrc.c
io_uring/rsrc.h
io_uring/splice.c

index 9d96481e2eb60c265e02436f3e4ff18e75180ffd..8da0d9e4533a190d7919cfdae22b5dfd2a27f65c 100644 (file)
@@ -178,9 +178,14 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *file)
        }
        seq_printf(m, "UserBufs:\t%u\n", ctx->buf_table.nr);
        for (i = 0; has_lock && i < ctx->buf_table.nr; i++) {
-               struct io_mapped_ubuf *buf = ctx->buf_table.nodes[i]->buf;
+               struct io_mapped_ubuf *buf = NULL;
 
-               seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf, buf->len);
+               if (ctx->buf_table.nodes[i])
+                       buf = ctx->buf_table.nodes[i]->buf;
+               if (buf)
+                       seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf, buf->len);
+               else
+                       seq_printf(m, "%5u: <none>\n", i);
        }
        if (has_lock && !xa_empty(&ctx->personalities)) {
                unsigned long index;
index 3a535e9e8ac381d7d7ed78a2209277a528beae35..44a772013c097eadacf1d0a855c12c6dcd1895ac 100644 (file)
@@ -947,8 +947,8 @@ void io_req_defer_failed(struct io_kiocb *req, s32 res)
 static void io_preinit_req(struct io_kiocb *req, struct io_ring_ctx *ctx)
 {
        req->ctx = ctx;
-       req->rsrc_nodes[IORING_RSRC_FILE] = rsrc_empty_node;
-       req->rsrc_nodes[IORING_RSRC_BUFFER] = rsrc_empty_node;
+       req->rsrc_nodes[IORING_RSRC_FILE] = NULL;
+       req->rsrc_nodes[IORING_RSRC_BUFFER] = NULL;
        req->link = NULL;
        req->async_data = NULL;
        /* not necessary, but safer to zero */
index 44bf21c0f8103ece7b7f8f46693772f62959cda1..4f02e969cf08c0eba24422ade878a4b059a67807 100644 (file)
@@ -117,8 +117,8 @@ struct io_kiocb *io_alloc_notif(struct io_ring_ctx *ctx)
        notif->file = NULL;
        notif->task = current;
        io_get_task_refs(1);
-       notif->rsrc_nodes[IORING_RSRC_FILE] = rsrc_empty_node;
-       notif->rsrc_nodes[IORING_RSRC_BUFFER] = rsrc_empty_node;
+       notif->rsrc_nodes[IORING_RSRC_FILE] = NULL;
+       notif->rsrc_nodes[IORING_RSRC_BUFFER] = NULL;
 
        nd = io_notif_to_data(notif);
        nd->zc_report = false;
index 378f337464572cec89fe273db9008a58c4730dd8..7ad91f1805661f65313b5840bc60711e97b5c5f3 100644 (file)
@@ -32,17 +32,6 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
 #define IORING_MAX_FIXED_FILES (1U << 20)
 #define IORING_MAX_REG_BUFFERS (1U << 14)
 
-static const struct io_mapped_ubuf dummy_ubuf = {
-       /* set invalid range, so io_import_fixed() fails meeting it */
-       .ubuf = -1UL,
-       .len = UINT_MAX,
-};
-
-const struct io_rsrc_node empty_node = {
-       .type = IORING_RSRC_BUFFER,
-       .buf = (struct io_mapped_ubuf *) &dummy_ubuf,
-};
-
 int __io_account_mem(struct user_struct *user, unsigned long nr_pages)
 {
        unsigned long page_limit, cur_pages, new_pages;
@@ -116,7 +105,7 @@ static void io_buffer_unmap(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
 {
        unsigned int i;
 
-       if (node->buf != &dummy_ubuf) {
+       if (node->buf) {
                struct io_mapped_ubuf *imu = node->buf;
 
                if (!refcount_dec_and_test(&imu->refs))
@@ -265,20 +254,21 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
                err = io_buffer_validate(iov);
                if (err)
                        break;
-               if (!iov->iov_base && tag) {
-                       err = -EINVAL;
-                       break;
-               }
                node = io_sqe_buffer_register(ctx, iov, &last_hpage);
                if (IS_ERR(node)) {
                        err = PTR_ERR(node);
                        break;
                }
+               if (tag) {
+                       if (!node) {
+                               err = -EINVAL;
+                               break;
+                       }
+                       node->tag = tag;
+               }
                i = array_index_nospec(up->offset + done, ctx->buf_table.nr);
                io_reset_rsrc_node(&ctx->buf_table, i);
                ctx->buf_table.nodes[i] = node;
-               if (tag)
-                       node->tag = tag;
                if (ctx->compat)
                        user_data += sizeof(struct compat_iovec);
                else
@@ -591,8 +581,11 @@ static bool headpage_already_acct(struct io_ring_ctx *ctx, struct page **pages,
        /* check previously registered pages */
        for (i = 0; i < ctx->buf_table.nr; i++) {
                struct io_rsrc_node *node = ctx->buf_table.nodes[i];
-               struct io_mapped_ubuf *imu = node->buf;
+               struct io_mapped_ubuf *imu;
 
+               if (!node)
+                       continue;
+               imu = node->buf;
                for (j = 0; j < imu->nr_bvecs; j++) {
                        if (!PageCompound(imu->bvec[j].bv_page))
                                continue;
@@ -742,7 +735,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
        bool coalesced;
 
        if (!iov->iov_base)
-               return rsrc_empty_node;
+               return NULL;
 
        node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
        if (!node)
@@ -850,10 +843,6 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
                                ret = -EFAULT;
                                break;
                        }
-                       if (tag && !iov->iov_base) {
-                               ret = -EINVAL;
-                               break;
-                       }
                }
 
                node = io_sqe_buffer_register(ctx, iov, &last_hpage);
@@ -861,8 +850,13 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
                        ret = PTR_ERR(node);
                        break;
                }
-               if (tag)
+               if (tag) {
+                       if (!node) {
+                               ret = -EINVAL;
+                               break;
+                       }
                        node->tag = tag;
+               }
                data.nodes[i] = node;
        }
 
@@ -957,8 +951,8 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
                struct io_rsrc_node *dst_node, *src_node;
 
                src_node = io_rsrc_node_lookup(&src_ctx->buf_table, i);
-               if (src_node == rsrc_empty_node) {
-                       dst_node = rsrc_empty_node;
+               if (!src_node) {
+                       dst_node = NULL;
                } else {
                        dst_node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
                        if (!dst_node) {
index 43b19e516f5fd86b9f5a7eff7380f0639d1cc21f..a40fad783a69418c075da22cf875cfbbe8e75d1e 100644 (file)
@@ -67,9 +67,6 @@ int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg,
 int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg,
                        unsigned int size, unsigned int type);
 
-extern const struct io_rsrc_node empty_node;
-#define rsrc_empty_node        (struct io_rsrc_node *) &empty_node
-
 static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data,
                                                       int index)
 {
@@ -80,7 +77,7 @@ static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data
 
 static inline void io_put_rsrc_node(struct io_rsrc_node *node)
 {
-       if (node != rsrc_empty_node && !--node->refs)
+       if (node && !--node->refs)
                io_free_rsrc_node(node);
 }
 
@@ -97,23 +94,17 @@ static inline bool io_reset_rsrc_node(struct io_rsrc_data *data, int index)
 
 static inline void io_req_put_rsrc_nodes(struct io_kiocb *req)
 {
-       if (req->rsrc_nodes[IORING_RSRC_FILE] != rsrc_empty_node) {
-               io_put_rsrc_node(req->rsrc_nodes[IORING_RSRC_FILE]);
-               req->rsrc_nodes[IORING_RSRC_FILE] = rsrc_empty_node;
-       }
-       if (req->rsrc_nodes[IORING_RSRC_BUFFER] != rsrc_empty_node) {
-               io_put_rsrc_node(req->rsrc_nodes[IORING_RSRC_BUFFER]);
-               req->rsrc_nodes[IORING_RSRC_BUFFER] = rsrc_empty_node;
-       }
+       io_put_rsrc_node(req->rsrc_nodes[IORING_RSRC_FILE]);
+       io_put_rsrc_node(req->rsrc_nodes[IORING_RSRC_BUFFER]);
+       req->rsrc_nodes[IORING_RSRC_FILE] = NULL;
+       req->rsrc_nodes[IORING_RSRC_BUFFER] = NULL;
 }
 
 static inline void io_req_assign_rsrc_node(struct io_kiocb *req,
                                           struct io_rsrc_node *node)
 {
-       if (node != rsrc_empty_node) {
-               node->refs++;
-               req->rsrc_nodes[node->type] = node;
-       }
+       node->refs++;
+       req->rsrc_nodes[node->type] = node;
 }
 
 int io_files_update(struct io_kiocb *req, unsigned int issue_flags);
index deeb8bb18651eb5cb8addd74521c58260474c302..e8ed15f4ea1a548f0287f079193f71718cb54b87 100644 (file)
@@ -35,7 +35,7 @@ static int __io_splice_prep(struct io_kiocb *req,
        if (unlikely(sp->flags & ~valid_flags))
                return -EINVAL;
        sp->splice_fd_in = READ_ONCE(sqe->splice_fd_in);
-       sp->rsrc_node = rsrc_empty_node;
+       sp->rsrc_node = NULL;
        req->flags |= REQ_F_FORCE_ASYNC;
        return 0;
 }