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.
Unified · Split
| @@ -7589,7 +7589,7 @@ static struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx) · 7588 unmodified lines | |||
| 7589 | } | 7589 | } |
| 7590 | 7590 | ||
| 7591 | static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, | 7591 | 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) |
| 7593 | { | 7593 | { |
| 7594 | __s32 __user *fds = (__s32 __user *) arg; | 7594 | __s32 __user *fds = (__s32 __user *) arg; |
| 7595 | struct file *file; | 7595 | struct file *file; |
| @@ -7616,17 +7616,24 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, · 20 unmodified lines | |||
| 7616 | goto out_free; | 7616 | goto out_free; |
| 7617 | 7617 | ||
| 7618 | for (i = 0; i < nr_args; i++, ctx->nr_user_files++) { | 7618 | 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))) { | ||
| 7620 | ret = -EFAULT; | 7623 | ret = -EFAULT; |
| 7621 | goto out_fput; | 7624 | goto out_fput; |
| 7622 | } | 7625 | } |
| 7623 | /* allow sparse sets */ | 7626 | /* allow sparse sets */ |
| 7624 | if (fd == -1) | 7627 | if (fd == -1) { |
| 7628 | ret = -EINVAL; | ||
| 7629 | if (unlikely(tag)) | ||
| 7630 | goto out_fput; | ||
| 7625 | continue; | 7631 | continue; |
| 7632 | } | ||
| 7626 | 7633 | ||
| 7627 | file = fget(fd); | 7634 | file = fget(fd); |
| 7628 | ret = -EBADF; | 7635 | ret = -EBADF; |
| 7629 | if (!file) | 7636 | if (unlikely(!file)) |
| 7630 | goto out_fput; | 7637 | goto out_fput; |
| 7631 | 7638 | ||
| 7632 | /* | 7639 | /* |
| @@ -7640,6 +7647,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, · 7 unmodified lines | |||
| 7640 | fput(file); | 7647 | fput(file); |
| 7641 | goto out_fput; | 7648 | goto out_fput; |
| 7642 | } | 7649 | } |
| 7650 | ctx->file_data->tags[i] = tag; | ||
| 7643 | io_fixed_file_set(io_fixed_file_slot(&ctx->file_table, i), file); | 7651 | io_fixed_file_set(io_fixed_file_slot(&ctx->file_table, i), file); |
| 7644 | } | 7652 | } |
| 7645 | 7653 | ||
| @@ -9743,6 +9751,29 @@ static int io_register_rsrc_update(struct io_ring_ctx *ctx, unsigned type, · 2097 unmodified lines | |||
| 9743 | return __io_register_rsrc_update(ctx, type, &up, nr_args); | 9751 | return __io_register_rsrc_update(ctx, type, &up, nr_args); |
| 9744 | } | 9752 | } |
| 9745 | 9753 | ||
| 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 | |||
| 9746 | static bool io_register_op_must_quiesce(int op) | 9777 | static bool io_register_op_must_quiesce(int op) |
| 9747 | { | 9778 | { |
| 9748 | switch (op) { | 9779 | switch (op) { |
| @@ -9752,6 +9783,7 @@ static bool io_register_op_must_quiesce(int op) · 3 unmodified lines | |||
| 9752 | case IORING_REGISTER_PROBE: | 9783 | case IORING_REGISTER_PROBE: |
| 9753 | case IORING_REGISTER_PERSONALITY: | 9784 | case IORING_REGISTER_PERSONALITY: |
| 9754 | case IORING_UNREGISTER_PERSONALITY: | 9785 | case IORING_UNREGISTER_PERSONALITY: |
| 9786 | case IORING_REGISTER_RSRC: | ||
| 9755 | return false; | 9787 | return false; |
| 9756 | default: | 9788 | default: |
| 9757 | return true; | 9789 | return true; |
| @@ -9820,7 +9852,7 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, · 62 unmodified lines | |||
| 9820 | ret = io_sqe_buffers_unregister(ctx); | 9852 | ret = io_sqe_buffers_unregister(ctx); |
| 9821 | break; | 9853 | break; |
| 9822 | case IORING_REGISTER_FILES: | 9854 | 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); |
| 9824 | break; | 9856 | break; |
| 9825 | case IORING_UNREGISTER_FILES: | 9857 | case IORING_UNREGISTER_FILES: |
| 9826 | ret = -EINVAL; | 9858 | ret = -EINVAL; |
| @@ -9877,6 +9909,9 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, · 50 unmodified lines | |||
| 9877 | case IORING_REGISTER_RESTRICTIONS: | 9909 | case IORING_REGISTER_RESTRICTIONS: |
| 9878 | ret = io_register_restrictions(ctx, arg, nr_args); | 9910 | ret = io_register_restrictions(ctx, arg, nr_args); |
| 9879 | break; | 9911 | break; |
| 9912 | case IORING_REGISTER_RSRC: | ||
| 9913 | ret = io_register_rsrc(ctx, arg, nr_args); | ||
| 9914 | break; | ||
| 9880 | default: | 9915 | default: |
| 9881 | ret = -EINVAL; | 9916 | ret = -EINVAL; |
| 9882 | break; | 9917 | break; |
| @@ -298,6 +298,7 @@ enum { · 297 unmodified lines | |||
| 298 | IORING_UNREGISTER_PERSONALITY = 10, | 298 | IORING_UNREGISTER_PERSONALITY = 10, |
| 299 | IORING_REGISTER_RESTRICTIONS = 11, | 299 | IORING_REGISTER_RESTRICTIONS = 11, |
| 300 | IORING_REGISTER_ENABLE_RINGS = 12, | 300 | IORING_REGISTER_ENABLE_RINGS = 12, |
| 301 | IORING_REGISTER_RSRC = 13, | ||
| 301 | 302 | ||
| 302 | /* this goes last */ | 303 | /* this goes last */ |
| 303 | IORING_REGISTER_LAST | 304 | IORING_REGISTER_LAST |
| @@ -320,6 +321,13 @@ enum { · 16 unmodified lines | |||
| 320 | IORING_RSRC_FILE = 0, | 321 | IORING_RSRC_FILE = 0, |
| 321 | }; | 322 | }; |
| 322 | 323 | ||
| 324 | struct io_uring_rsrc_register { | ||
| 325 | __u32 type; | ||
| 326 | __u32 nr; | ||
| 327 | __aligned_u64 data; | ||
| 328 | __aligned_u64 tags; | ||
| 329 | }; | ||
| 330 | |||
| 323 | /* Skip updating fd indexes set to this value in the fd table */ | 331 | /* Skip updating fd indexes set to this value in the fd table */ |
| 324 | #define IORING_REGISTER_FILES_SKIP (-2) | 332 | #define IORING_REGISTER_FILES_SKIP (-2) |
| 325 | 333 | ||