Skip to content

Commit

Permalink
io_uring: allow allocated fixed files for openat/openat2
Browse files Browse the repository at this point in the history
If the applications passes in UINT_MAX as the file_slot, then that's a
hint to allocate a fixed file descriptor rather than have one be passed
in directly.

This can be useful for having io_uring manage the direct descriptor space.

Normal open direct requests will complete with 0 for success, and < 0
in case of error. If io_uring is asked to allocated the direct descriptor,
then the direct descriptor is returned in case of success.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
axboe committed May 8, 2022
1 parent 8fc20c7 commit 8e0d731
Showing 1 changed file with 28 additions and 3 deletions.
31 changes: 28 additions & 3 deletions fs/io_uring.c
Expand Up @@ -4702,7 +4702,7 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return __io_openat_prep(req, sqe);
}

static int __maybe_unused 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;
Expand All @@ -4728,6 +4728,31 @@ static int __maybe_unused io_file_bitmap_get(struct io_ring_ctx *ctx)
return -ENFILE;
}

static int io_fixed_file_install(struct io_kiocb *req, unsigned int issue_flags,
struct file *file, unsigned int file_slot)
{
int alloc_slot = file_slot == UINT_MAX;
struct io_ring_ctx *ctx = req->ctx;
int ret;

if (alloc_slot) {
io_ring_submit_lock(ctx, issue_flags);
file_slot = io_file_bitmap_get(ctx);
if (unlikely(file_slot < 0)) {
io_ring_submit_unlock(ctx, issue_flags);
return ret;
}
}

ret = io_install_fixed_file(req, file, issue_flags, file_slot);
if (alloc_slot) {
io_ring_submit_unlock(ctx, issue_flags);
return file_slot;
}

return ret;
}

static int io_openat2(struct io_kiocb *req, unsigned int issue_flags)
{
struct open_flags op;
Expand Down Expand Up @@ -4783,8 +4808,8 @@ static int io_openat2(struct io_kiocb *req, unsigned int issue_flags)
if (!fixed)
fd_install(ret, file);
else
ret = io_install_fixed_file(req, file, issue_flags,
req->open.file_slot - 1);
ret = io_fixed_file_install(req, issue_flags, file,
req->open.file_slot);
err:
putname(req->open.filename);
req->flags &= ~REQ_F_NEED_CLEANUP;
Expand Down

0 comments on commit 8e0d731

Please sign in to comment.