Skip to content

Commit c3bdad0

Browse files
isilenceaxboe
authored andcommitted
io_uring: add generic rsrc update with tags
Add IORING_REGISTER_RSRC_UPDATE, which also supports passing in rsrc tags. Implement it for registered files. Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/d4dc66df204212f64835ffca2c4eb5e8363f2f05.1619356238.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 792e358 commit c3bdad0

File tree

2 files changed

+57
-17
lines changed

2 files changed

+57
-17
lines changed

fs/io_uring.c

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@ static void io_put_task(struct task_struct *task, int nr);
10361036
static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req);
10371037
static void io_queue_linked_timeout(struct io_kiocb *req);
10381038
static int __io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
1039-
struct io_uring_rsrc_update *up,
1039+
struct io_uring_rsrc_update2 *up,
10401040
unsigned nr_args);
10411041
static void io_clean_op(struct io_kiocb *req);
10421042
static struct file *io_file_get(struct io_submit_state *state,
@@ -5814,14 +5814,16 @@ static int io_rsrc_update_prep(struct io_kiocb *req,
58145814
static int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
58155815
{
58165816
struct io_ring_ctx *ctx = req->ctx;
5817-
struct io_uring_rsrc_update up;
5817+
struct io_uring_rsrc_update2 up;
58185818
int ret;
58195819

58205820
if (issue_flags & IO_URING_F_NONBLOCK)
58215821
return -EAGAIN;
58225822

58235823
up.offset = req->rsrc_update.offset;
58245824
up.data = req->rsrc_update.arg;
5825+
up.nr = 0;
5826+
up.tags = 0;
58255827

58265828
mutex_lock(&ctx->uring_lock);
58275829
ret = __io_register_rsrc_update(ctx, IORING_RSRC_FILE,
@@ -7732,9 +7734,10 @@ static int io_queue_rsrc_removal(struct io_rsrc_data *data, unsigned idx,
77327734
}
77337735

77347736
static int __io_sqe_files_update(struct io_ring_ctx *ctx,
7735-
struct io_uring_rsrc_update *up,
7737+
struct io_uring_rsrc_update2 *up,
77367738
unsigned nr_args)
77377739
{
7740+
u64 __user *tags = u64_to_user_ptr(up->tags);
77387741
__s32 __user *fds = u64_to_user_ptr(up->data);
77397742
struct io_rsrc_data *data = ctx->file_data;
77407743
struct io_fixed_file *file_slot;
@@ -7749,10 +7752,17 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
77497752
return -EINVAL;
77507753

77517754
for (done = 0; done < nr_args; done++) {
7752-
if (copy_from_user(&fd, &fds[done], sizeof(fd))) {
7755+
u64 tag = 0;
7756+
7757+
if ((tags && copy_from_user(&tag, &tags[done], sizeof(tag))) ||
7758+
copy_from_user(&fd, &fds[done], sizeof(fd))) {
77537759
err = -EFAULT;
77547760
break;
77557761
}
7762+
if ((fd == IORING_REGISTER_FILES_SKIP || fd == -1) && tag) {
7763+
err = -EINVAL;
7764+
break;
7765+
}
77567766
if (fd == IORING_REGISTER_FILES_SKIP)
77577767
continue;
77587768

@@ -7787,6 +7797,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
77877797
err = -EBADF;
77887798
break;
77897799
}
7800+
data->tags[up->offset + done] = tag;
77907801
io_fixed_file_set(file_slot, file);
77917802
err = io_sqe_file_register(ctx, file, i);
77927803
if (err) {
@@ -9718,12 +9729,14 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx)
97189729
}
97199730

97209731
static int __io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
9721-
struct io_uring_rsrc_update *up,
9732+
struct io_uring_rsrc_update2 *up,
97229733
unsigned nr_args)
97239734
{
97249735
__u32 tmp;
97259736
int err;
97269737

9738+
if (up->resv)
9739+
return -EINVAL;
97279740
if (check_add_overflow(up->offset, nr_args, &tmp))
97289741
return -EOVERFLOW;
97299742
err = io_rsrc_node_switch_start(ctx);
@@ -9737,18 +9750,31 @@ static int __io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
97379750
return -EINVAL;
97389751
}
97399752

9740-
static int io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type,
9741-
void __user *arg, unsigned nr_args)
9753+
static int io_register_files_update(struct io_ring_ctx *ctx, void __user *arg,
9754+
unsigned nr_args)
97429755
{
9743-
struct io_uring_rsrc_update up;
9756+
struct io_uring_rsrc_update2 up;
97449757

97459758
if (!nr_args)
97469759
return -EINVAL;
9760+
memset(&up, 0, sizeof(up));
9761+
if (copy_from_user(&up, arg, sizeof(struct io_uring_rsrc_update)))
9762+
return -EFAULT;
9763+
return __io_register_rsrc_update(ctx, IORING_RSRC_FILE, &up, nr_args);
9764+
}
9765+
9766+
static int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg,
9767+
unsigned size)
9768+
{
9769+
struct io_uring_rsrc_update2 up;
9770+
9771+
if (size != sizeof(up))
9772+
return -EINVAL;
97479773
if (copy_from_user(&up, arg, sizeof(up)))
97489774
return -EFAULT;
9749-
if (up.resv)
9775+
if (!up.nr)
97509776
return -EINVAL;
9751-
return __io_register_rsrc_update(ctx, type, &up, nr_args);
9777+
return __io_register_rsrc_update(ctx, up.type, &up, up.nr);
97529778
}
97539779

97549780
static int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg,
@@ -9784,6 +9810,7 @@ static bool io_register_op_must_quiesce(int op)
97849810
case IORING_REGISTER_PERSONALITY:
97859811
case IORING_UNREGISTER_PERSONALITY:
97869812
case IORING_REGISTER_RSRC:
9813+
case IORING_REGISTER_RSRC_UPDATE:
97879814
return false;
97889815
default:
97899816
return true;
@@ -9861,7 +9888,7 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
98619888
ret = io_sqe_files_unregister(ctx);
98629889
break;
98639890
case IORING_REGISTER_FILES_UPDATE:
9864-
ret = io_register_rsrc_update(ctx, IORING_RSRC_FILE, arg, nr_args);
9891+
ret = io_register_files_update(ctx, arg, nr_args);
98659892
break;
98669893
case IORING_REGISTER_EVENTFD:
98679894
case IORING_REGISTER_EVENTFD_ASYNC:
@@ -9912,6 +9939,9 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
99129939
case IORING_REGISTER_RSRC:
99139940
ret = io_register_rsrc(ctx, arg, nr_args);
99149941
break;
9942+
case IORING_REGISTER_RSRC_UPDATE:
9943+
ret = io_register_rsrc_update(ctx, arg, nr_args);
9944+
break;
99159945
default:
99169946
ret = -EINVAL;
99179947
break;

include/uapi/linux/io_uring.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ enum {
299299
IORING_REGISTER_RESTRICTIONS = 11,
300300
IORING_REGISTER_ENABLE_RINGS = 12,
301301
IORING_REGISTER_RSRC = 13,
302+
IORING_REGISTER_RSRC_UPDATE = 14,
302303

303304
/* this goes last */
304305
IORING_REGISTER_LAST
@@ -311,12 +312,6 @@ struct io_uring_files_update {
311312
__aligned_u64 /* __s32 * */ fds;
312313
};
313314

314-
struct io_uring_rsrc_update {
315-
__u32 offset;
316-
__u32 resv;
317-
__aligned_u64 data;
318-
};
319-
320315
enum {
321316
IORING_RSRC_FILE = 0,
322317
};
@@ -328,6 +323,21 @@ struct io_uring_rsrc_register {
328323
__aligned_u64 tags;
329324
};
330325

326+
struct io_uring_rsrc_update {
327+
__u32 offset;
328+
__u32 resv;
329+
__aligned_u64 data;
330+
};
331+
332+
struct io_uring_rsrc_update2 {
333+
__u32 offset;
334+
__u32 resv;
335+
__aligned_u64 data;
336+
__aligned_u64 tags;
337+
__u32 type;
338+
__u32 nr;
339+
};
340+
331341
/* Skip updating fd indexes set to this value in the fd table */
332342
#define IORING_REGISTER_FILES_SKIP (-2)
333343

0 commit comments

Comments
 (0)