unsigned nr_args);
static void io_clean_op(struct io_kiocb *req);
static struct file *io_file_get(struct io_ring_ctx *ctx,
- struct io_kiocb *req, int fd, bool fixed);
+ struct io_kiocb *req, int fd, bool fixed,
+ unsigned int issue_flags);
static void __io_queue_sqe(struct io_kiocb *req);
static void io_rsrc_put_work(struct work_struct *work);
return -EAGAIN;
in = io_file_get(req->ctx, req, sp->splice_fd_in,
- (sp->flags & SPLICE_F_FD_IN_FIXED));
+ (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags);
if (!in) {
ret = -EBADF;
goto done;
return -EAGAIN;
in = io_file_get(req->ctx, req, sp->splice_fd_in,
- (sp->flags & SPLICE_F_FD_IN_FIXED));
+ (sp->flags & SPLICE_F_FD_IN_FIXED), issue_flags);
if (!in) {
ret = -EBADF;
goto done;
}
static inline struct file *io_file_get_fixed(struct io_ring_ctx *ctx,
- struct io_kiocb *req, int fd)
+ struct io_kiocb *req, int fd,
+ unsigned int issue_flags)
{
- struct file *file;
+ struct file *file = NULL;
unsigned long file_ptr;
+ io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
+
if (unlikely((unsigned int)fd >= ctx->nr_user_files))
- return NULL;
+ goto out;
fd = array_index_nospec(fd, ctx->nr_user_files);
file_ptr = io_fixed_file_slot(&ctx->file_table, fd)->file_ptr;
file = (struct file *) (file_ptr & FFS_MASK);
/* mask in overlapping REQ_F and FFS bits */
req->flags |= (file_ptr << REQ_F_NOWAIT_READ_BIT);
io_req_set_rsrc_node(req);
+out:
+ io_ring_submit_unlock(ctx, !(issue_flags & IO_URING_F_NONBLOCK));
return file;
}
}
static inline struct file *io_file_get(struct io_ring_ctx *ctx,
- struct io_kiocb *req, int fd, bool fixed)
+ struct io_kiocb *req, int fd, bool fixed,
+ unsigned int issue_flags)
{
if (fixed)
- return io_file_get_fixed(ctx, req, fd);
+ return io_file_get_fixed(ctx, req, fd, issue_flags);
else
return io_file_get_normal(ctx, req, fd);
}
if (io_op_defs[req->opcode].needs_file) {
req->file = io_file_get(ctx, req, READ_ONCE(sqe->fd),
- (sqe_flags & IOSQE_FIXED_FILE));
+ (sqe_flags & IOSQE_FIXED_FILE), 0);
if (unlikely(!req->file))
ret = -EBADF;
}