Skip to content

Commit a3e4bc2

Browse files
committed
io_uring: defer splice/tee file validity check until command issue
In preparation for not using the file at prep time, defer checking if this file refers to a valid io_uring instance until issue time. This also means we can get rid of the cleanup flag for splice and tee. Cc: stable@vger.kernel.org # v5.15+ Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent ec858af commit a3e4bc2

1 file changed

Lines changed: 21 additions & 28 deletions

File tree

fs/io_uring.c

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -654,10 +654,10 @@ struct io_epoll {
654654

655655
struct io_splice {
656656
struct file *file_out;
657-
struct file *file_in;
658657
loff_t off_out;
659658
loff_t off_in;
660659
u64 len;
660+
int splice_fd_in;
661661
unsigned int flags;
662662
};
663663

@@ -1687,14 +1687,6 @@ static void io_prep_async_work(struct io_kiocb *req)
16871687
if (def->unbound_nonreg_file)
16881688
req->work.flags |= IO_WQ_WORK_UNBOUND;
16891689
}
1690-
1691-
switch (req->opcode) {
1692-
case IORING_OP_SPLICE:
1693-
case IORING_OP_TEE:
1694-
if (!S_ISREG(file_inode(req->splice.file_in)->i_mode))
1695-
req->work.flags |= IO_WQ_WORK_UNBOUND;
1696-
break;
1697-
}
16981690
}
16991691

17001692
static void io_prep_async_link(struct io_kiocb *req)
@@ -4369,18 +4361,11 @@ static int __io_splice_prep(struct io_kiocb *req,
43694361
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
43704362
return -EINVAL;
43714363

4372-
sp->file_in = NULL;
43734364
sp->len = READ_ONCE(sqe->len);
43744365
sp->flags = READ_ONCE(sqe->splice_flags);
4375-
43764366
if (unlikely(sp->flags & ~valid_flags))
43774367
return -EINVAL;
4378-
4379-
sp->file_in = io_file_get(req->ctx, req, READ_ONCE(sqe->splice_fd_in),
4380-
(sp->flags & SPLICE_F_FD_IN_FIXED));
4381-
if (!sp->file_in)
4382-
return -EBADF;
4383-
req->flags |= REQ_F_NEED_CLEANUP;
4368+
sp->splice_fd_in = READ_ONCE(sqe->splice_fd_in);
43844369
return 0;
43854370
}
43864371

@@ -4395,20 +4380,27 @@ static int io_tee_prep(struct io_kiocb *req,
43954380
static int io_tee(struct io_kiocb *req, unsigned int issue_flags)
43964381
{
43974382
struct io_splice *sp = &req->splice;
4398-
struct file *in = sp->file_in;
43994383
struct file *out = sp->file_out;
44004384
unsigned int flags = sp->flags & ~SPLICE_F_FD_IN_FIXED;
4385+
struct file *in;
44014386
long ret = 0;
44024387

44034388
if (issue_flags & IO_URING_F_NONBLOCK)
44044389
return -EAGAIN;
4390+
4391+
in = io_file_get(req->ctx, req, sp->splice_fd_in,
4392+
(sp->flags & SPLICE_F_FD_IN_FIXED));
4393+
if (!in) {
4394+
ret = -EBADF;
4395+
goto done;
4396+
}
4397+
44054398
if (sp->len)
44064399
ret = do_tee(in, out, sp->len, flags);
44074400

44084401
if (!(sp->flags & SPLICE_F_FD_IN_FIXED))
44094402
io_put_file(in);
4410-
req->flags &= ~REQ_F_NEED_CLEANUP;
4411-
4403+
done:
44124404
if (ret != sp->len)
44134405
req_set_fail(req);
44144406
io_req_complete(req, ret);
@@ -4427,15 +4419,22 @@ static int io_splice_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
44274419
static int io_splice(struct io_kiocb *req, unsigned int issue_flags)
44284420
{
44294421
struct io_splice *sp = &req->splice;
4430-
struct file *in = sp->file_in;
44314422
struct file *out = sp->file_out;
44324423
unsigned int flags = sp->flags & ~SPLICE_F_FD_IN_FIXED;
44334424
loff_t *poff_in, *poff_out;
4425+
struct file *in;
44344426
long ret = 0;
44354427

44364428
if (issue_flags & IO_URING_F_NONBLOCK)
44374429
return -EAGAIN;
44384430

4431+
in = io_file_get(req->ctx, req, sp->splice_fd_in,
4432+
(sp->flags & SPLICE_F_FD_IN_FIXED));
4433+
if (!in) {
4434+
ret = -EBADF;
4435+
goto done;
4436+
}
4437+
44394438
poff_in = (sp->off_in == -1) ? NULL : &sp->off_in;
44404439
poff_out = (sp->off_out == -1) ? NULL : &sp->off_out;
44414440

@@ -4444,8 +4443,7 @@ static int io_splice(struct io_kiocb *req, unsigned int issue_flags)
44444443

44454444
if (!(sp->flags & SPLICE_F_FD_IN_FIXED))
44464445
io_put_file(in);
4447-
req->flags &= ~REQ_F_NEED_CLEANUP;
4448-
4446+
done:
44494447
if (ret != sp->len)
44504448
req_set_fail(req);
44514449
io_req_complete(req, ret);
@@ -7176,11 +7174,6 @@ static void io_clean_op(struct io_kiocb *req)
71767174
kfree(io->free_iov);
71777175
break;
71787176
}
7179-
case IORING_OP_SPLICE:
7180-
case IORING_OP_TEE:
7181-
if (!(req->splice.flags & SPLICE_F_FD_IN_FIXED))
7182-
io_put_file(req->splice.file_in);
7183-
break;
71847177
case IORING_OP_OPENAT:
71857178
case IORING_OP_OPENAT2:
71867179
if (req->open.filename)

0 commit comments

Comments
 (0)