Skip to content

Commit 792e358

Browse files
isilenceaxboe
authored andcommitted
io_uring: add IORING_REGISTER_RSRC
Add a new io_uring_register() opcode for rsrc registeration. Instead of accepting a pointer to resources, fds or iovecs, it @arg is now pointing to a struct io_uring_rsrc_register, and the second argument tells how large that struct is to make it easily extendible by adding new fields. All that is done mainly to be able to pass in a pointer with tags. Pass it in and enable CQE posting for file resources. Doesn't support setting tags on update yet. A design choice made here is to not post CQEs on rsrc de-registration, but only when we updated-removed it by rsrc dynamic update. Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/c498aaec32a4bb277b2406b9069662c02cdda98c.1619356238.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent fdecb66 commit 792e358

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

fs/io_uring.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7589,7 +7589,7 @@ static struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx)
75897589
}
75907590

75917591
static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
7592-
unsigned nr_args)
7592+
unsigned nr_args, u64 __user *tags)
75937593
{
75947594
__s32 __user *fds = (__s32 __user *) arg;
75957595
struct file *file;
@@ -7616,17 +7616,24 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
76167616
goto out_free;
76177617

76187618
for (i = 0; i < nr_args; i++, ctx->nr_user_files++) {
7619-
if (copy_from_user(&fd, &fds[i], sizeof(fd))) {
7619+
u64 tag = 0;
7620+
7621+
if ((tags && copy_from_user(&tag, &tags[i], sizeof(tag))) ||
7622+
copy_from_user(&fd, &fds[i], sizeof(fd))) {
76207623
ret = -EFAULT;
76217624
goto out_fput;
76227625
}
76237626
/* allow sparse sets */
7624-
if (fd == -1)
7627+
if (fd == -1) {
7628+
ret = -EINVAL;
7629+
if (unlikely(tag))
7630+
goto out_fput;
76257631
continue;
7632+
}
76267633

76277634
file = fget(fd);
76287635
ret = -EBADF;
7629-
if (!file)
7636+
if (unlikely(!file))
76307637
goto out_fput;
76317638

76327639
/*
@@ -7640,6 +7647,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
76407647
fput(file);
76417648
goto out_fput;
76427649
}
7650+
ctx->file_data->tags[i] = tag;
76437651
io_fixed_file_set(io_fixed_file_slot(&ctx->file_table, i), file);
76447652
}
76457653

@@ -9743,6 +9751,29 @@ static int io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
97439751
return __io_register_rsrc_update(ctx, type, &up, nr_args);
97449752
}
97459753

9754+
static int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg,
9755+
unsigned int size)
9756+
{
9757+
struct io_uring_rsrc_register rr;
9758+
9759+
/* keep it extendible */
9760+
if (size != sizeof(rr))
9761+
return -EINVAL;
9762+
9763+
memset(&rr, 0, sizeof(rr));
9764+
if (copy_from_user(&rr, arg, size))
9765+
return -EFAULT;
9766+
if (!rr.nr)
9767+
return -EINVAL;
9768+
9769+
switch (rr.type) {
9770+
case IORING_RSRC_FILE:
9771+
return io_sqe_files_register(ctx, u64_to_user_ptr(rr.data),
9772+
rr.nr, u64_to_user_ptr(rr.tags));
9773+
}
9774+
return -EINVAL;
9775+
}
9776+
97469777
static bool io_register_op_must_quiesce(int op)
97479778
{
97489779
switch (op) {
@@ -9752,6 +9783,7 @@ static bool io_register_op_must_quiesce(int op)
97529783
case IORING_REGISTER_PROBE:
97539784
case IORING_REGISTER_PERSONALITY:
97549785
case IORING_UNREGISTER_PERSONALITY:
9786+
case IORING_REGISTER_RSRC:
97559787
return false;
97569788
default:
97579789
return true;
@@ -9820,7 +9852,7 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
98209852
ret = io_sqe_buffers_unregister(ctx);
98219853
break;
98229854
case IORING_REGISTER_FILES:
9823-
ret = io_sqe_files_register(ctx, arg, nr_args);
9855+
ret = io_sqe_files_register(ctx, arg, nr_args, NULL);
98249856
break;
98259857
case IORING_UNREGISTER_FILES:
98269858
ret = -EINVAL;
@@ -9877,6 +9909,9 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
98779909
case IORING_REGISTER_RESTRICTIONS:
98789910
ret = io_register_restrictions(ctx, arg, nr_args);
98799911
break;
9912+
case IORING_REGISTER_RSRC:
9913+
ret = io_register_rsrc(ctx, arg, nr_args);
9914+
break;
98809915
default:
98819916
ret = -EINVAL;
98829917
break;

include/uapi/linux/io_uring.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ enum {
298298
IORING_UNREGISTER_PERSONALITY = 10,
299299
IORING_REGISTER_RESTRICTIONS = 11,
300300
IORING_REGISTER_ENABLE_RINGS = 12,
301+
IORING_REGISTER_RSRC = 13,
301302

302303
/* this goes last */
303304
IORING_REGISTER_LAST
@@ -320,6 +321,13 @@ enum {
320321
IORING_RSRC_FILE = 0,
321322
};
322323

324+
struct io_uring_rsrc_register {
325+
__u32 type;
326+
__u32 nr;
327+
__aligned_u64 data;
328+
__aligned_u64 tags;
329+
};
330+
323331
/* Skip updating fd indexes set to this value in the fd table */
324332
#define IORING_REGISTER_FILES_SKIP (-2)
325333

0 commit comments

Comments
 (0)