Skip to content

Commit 1d3962a

Browse files
committed
Merge tag 'io_uring-5.7-2020-05-08' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe: - Fix finish_wait() balancing in file cancelation (Xiaoguang) - Ensure early cleanup of resources in ring map failure (Xiaoguang) - Ensure IORING_OP_SLICE does the right file mode checks (Pavel) - Remove file opening from openat/openat2/statx, it's not needed and messes with O_PATH * tag 'io_uring-5.7-2020-05-08' of git://git.kernel.dk/linux-block: io_uring: don't use 'fd' for openat/openat2/statx splice: move f_mode checks to do_{splice,tee}() io_uring: handle -EFAULT properly in io_uring_setup() io_uring: fix mismatched finish_wait() calls in io_uring_cancel_files()
2 parents d5eeab8 + 63ff822 commit 1d3962a

File tree

2 files changed

+40
-70
lines changed

2 files changed

+40
-70
lines changed

fs/io_uring.c

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -680,8 +680,6 @@ struct io_op_def {
680680
unsigned needs_mm : 1;
681681
/* needs req->file assigned */
682682
unsigned needs_file : 1;
683-
/* needs req->file assigned IFF fd is >= 0 */
684-
unsigned fd_non_neg : 1;
685683
/* hash wq insertion if file is a regular file */
686684
unsigned hash_reg_file : 1;
687685
/* unbound wq insertion if file is a non-regular file */
@@ -784,8 +782,6 @@ static const struct io_op_def io_op_defs[] = {
784782
.needs_file = 1,
785783
},
786784
[IORING_OP_OPENAT] = {
787-
.needs_file = 1,
788-
.fd_non_neg = 1,
789785
.file_table = 1,
790786
.needs_fs = 1,
791787
},
@@ -799,8 +795,6 @@ static const struct io_op_def io_op_defs[] = {
799795
},
800796
[IORING_OP_STATX] = {
801797
.needs_mm = 1,
802-
.needs_file = 1,
803-
.fd_non_neg = 1,
804798
.needs_fs = 1,
805799
.file_table = 1,
806800
},
@@ -837,8 +831,6 @@ static const struct io_op_def io_op_defs[] = {
837831
.buffer_select = 1,
838832
},
839833
[IORING_OP_OPENAT2] = {
840-
.needs_file = 1,
841-
.fd_non_neg = 1,
842834
.file_table = 1,
843835
.needs_fs = 1,
844836
},
@@ -5368,15 +5360,6 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
53685360
io_steal_work(req, workptr);
53695361
}
53705362

5371-
static int io_req_needs_file(struct io_kiocb *req, int fd)
5372-
{
5373-
if (!io_op_defs[req->opcode].needs_file)
5374-
return 0;
5375-
if ((fd == -1 || fd == AT_FDCWD) && io_op_defs[req->opcode].fd_non_neg)
5376-
return 0;
5377-
return 1;
5378-
}
5379-
53805363
static inline struct file *io_file_from_index(struct io_ring_ctx *ctx,
53815364
int index)
53825365
{
@@ -5414,14 +5397,11 @@ static int io_file_get(struct io_submit_state *state, struct io_kiocb *req,
54145397
}
54155398

54165399
static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req,
5417-
int fd, unsigned int flags)
5400+
int fd)
54185401
{
54195402
bool fixed;
54205403

5421-
if (!io_req_needs_file(req, fd))
5422-
return 0;
5423-
5424-
fixed = (flags & IOSQE_FIXED_FILE);
5404+
fixed = (req->flags & REQ_F_FIXED_FILE) != 0;
54255405
if (unlikely(!fixed && req->needs_fixed_file))
54265406
return -EBADF;
54275407

@@ -5798,7 +5778,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
57985778
struct io_submit_state *state, bool async)
57995779
{
58005780
unsigned int sqe_flags;
5801-
int id, fd;
5781+
int id;
58025782

58035783
/*
58045784
* All io need record the previous position, if LINK vs DARIN,
@@ -5850,8 +5830,10 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
58505830
IOSQE_ASYNC | IOSQE_FIXED_FILE |
58515831
IOSQE_BUFFER_SELECT | IOSQE_IO_LINK);
58525832

5853-
fd = READ_ONCE(sqe->fd);
5854-
return io_req_set_file(state, req, fd, sqe_flags);
5833+
if (!io_op_defs[req->opcode].needs_file)
5834+
return 0;
5835+
5836+
return io_req_set_file(state, req, READ_ONCE(sqe->fd));
58555837
}
58565838

58575839
static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
@@ -7360,11 +7342,9 @@ static int io_uring_release(struct inode *inode, struct file *file)
73607342
static void io_uring_cancel_files(struct io_ring_ctx *ctx,
73617343
struct files_struct *files)
73627344
{
7363-
struct io_kiocb *req;
7364-
DEFINE_WAIT(wait);
7365-
73667345
while (!list_empty_careful(&ctx->inflight_list)) {
7367-
struct io_kiocb *cancel_req = NULL;
7346+
struct io_kiocb *cancel_req = NULL, *req;
7347+
DEFINE_WAIT(wait);
73687348

73697349
spin_lock_irq(&ctx->inflight_lock);
73707350
list_for_each_entry(req, &ctx->inflight_list, inflight_entry) {
@@ -7404,15 +7384,16 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx,
74047384
*/
74057385
if (refcount_sub_and_test(2, &cancel_req->refs)) {
74067386
io_put_req(cancel_req);
7387+
finish_wait(&ctx->inflight_wait, &wait);
74077388
continue;
74087389
}
74097390
}
74107391

74117392
io_wq_cancel_work(ctx->io_wq, &cancel_req->work);
74127393
io_put_req(cancel_req);
74137394
schedule();
7395+
finish_wait(&ctx->inflight_wait, &wait);
74147396
}
7415-
finish_wait(&ctx->inflight_wait, &wait);
74167397
}
74177398

74187399
static int io_uring_flush(struct file *file, void *data)
@@ -7761,7 +7742,8 @@ static int io_uring_get_fd(struct io_ring_ctx *ctx)
77617742
return ret;
77627743
}
77637744

7764-
static int io_uring_create(unsigned entries, struct io_uring_params *p)
7745+
static int io_uring_create(unsigned entries, struct io_uring_params *p,
7746+
struct io_uring_params __user *params)
77657747
{
77667748
struct user_struct *user = NULL;
77677749
struct io_ring_ctx *ctx;
@@ -7853,6 +7835,14 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
78537835
p->cq_off.overflow = offsetof(struct io_rings, cq_overflow);
78547836
p->cq_off.cqes = offsetof(struct io_rings, cqes);
78557837

7838+
p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP |
7839+
IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS |
7840+
IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL;
7841+
7842+
if (copy_to_user(params, p, sizeof(*p))) {
7843+
ret = -EFAULT;
7844+
goto err;
7845+
}
78567846
/*
78577847
* Install ring fd as the very last thing, so we don't risk someone
78587848
* having closed it before we finish setup
@@ -7861,9 +7851,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
78617851
if (ret < 0)
78627852
goto err;
78637853

7864-
p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP |
7865-
IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS |
7866-
IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL;
78677854
trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags);
78687855
return ret;
78697856
err:
@@ -7879,7 +7866,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
78797866
static long io_uring_setup(u32 entries, struct io_uring_params __user *params)
78807867
{
78817868
struct io_uring_params p;
7882-
long ret;
78837869
int i;
78847870

78857871
if (copy_from_user(&p, params, sizeof(p)))
@@ -7894,14 +7880,7 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params)
78947880
IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ))
78957881
return -EINVAL;
78967882

7897-
ret = io_uring_create(entries, &p);
7898-
if (ret < 0)
7899-
return ret;
7900-
7901-
if (copy_to_user(params, &p, sizeof(p)))
7902-
return -EFAULT;
7903-
7904-
return ret;
7883+
return io_uring_create(entries, &p, params);
79057884
}
79067885

79077886
SYSCALL_DEFINE2(io_uring_setup, u32, entries,

fs/splice.c

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,19 +1118,17 @@ long do_splice(struct file *in, loff_t __user *off_in,
11181118
loff_t offset;
11191119
long ret;
11201120

1121+
if (unlikely(!(in->f_mode & FMODE_READ) ||
1122+
!(out->f_mode & FMODE_WRITE)))
1123+
return -EBADF;
1124+
11211125
ipipe = get_pipe_info(in);
11221126
opipe = get_pipe_info(out);
11231127

11241128
if (ipipe && opipe) {
11251129
if (off_in || off_out)
11261130
return -ESPIPE;
11271131

1128-
if (!(in->f_mode & FMODE_READ))
1129-
return -EBADF;
1130-
1131-
if (!(out->f_mode & FMODE_WRITE))
1132-
return -EBADF;
1133-
11341132
/* Splicing to self would be fun, but... */
11351133
if (ipipe == opipe)
11361134
return -EINVAL;
@@ -1153,9 +1151,6 @@ long do_splice(struct file *in, loff_t __user *off_in,
11531151
offset = out->f_pos;
11541152
}
11551153

1156-
if (unlikely(!(out->f_mode & FMODE_WRITE)))
1157-
return -EBADF;
1158-
11591154
if (unlikely(out->f_flags & O_APPEND))
11601155
return -EINVAL;
11611156

@@ -1440,15 +1435,11 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
14401435
error = -EBADF;
14411436
in = fdget(fd_in);
14421437
if (in.file) {
1443-
if (in.file->f_mode & FMODE_READ) {
1444-
out = fdget(fd_out);
1445-
if (out.file) {
1446-
if (out.file->f_mode & FMODE_WRITE)
1447-
error = do_splice(in.file, off_in,
1448-
out.file, off_out,
1449-
len, flags);
1450-
fdput(out);
1451-
}
1438+
out = fdget(fd_out);
1439+
if (out.file) {
1440+
error = do_splice(in.file, off_in, out.file, off_out,
1441+
len, flags);
1442+
fdput(out);
14521443
}
14531444
fdput(in);
14541445
}
@@ -1770,6 +1761,10 @@ static long do_tee(struct file *in, struct file *out, size_t len,
17701761
struct pipe_inode_info *opipe = get_pipe_info(out);
17711762
int ret = -EINVAL;
17721763

1764+
if (unlikely(!(in->f_mode & FMODE_READ) ||
1765+
!(out->f_mode & FMODE_WRITE)))
1766+
return -EBADF;
1767+
17731768
/*
17741769
* Duplicate the contents of ipipe to opipe without actually
17751770
* copying the data.
@@ -1795,7 +1790,7 @@ static long do_tee(struct file *in, struct file *out, size_t len,
17951790

17961791
SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
17971792
{
1798-
struct fd in;
1793+
struct fd in, out;
17991794
int error;
18001795

18011796
if (unlikely(flags & ~SPLICE_F_ALL))
@@ -1807,14 +1802,10 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
18071802
error = -EBADF;
18081803
in = fdget(fdin);
18091804
if (in.file) {
1810-
if (in.file->f_mode & FMODE_READ) {
1811-
struct fd out = fdget(fdout);
1812-
if (out.file) {
1813-
if (out.file->f_mode & FMODE_WRITE)
1814-
error = do_tee(in.file, out.file,
1815-
len, flags);
1816-
fdput(out);
1817-
}
1805+
out = fdget(fdout);
1806+
if (out.file) {
1807+
error = do_tee(in.file, out.file, len, flags);
1808+
fdput(out);
18181809
}
18191810
fdput(in);
18201811
}

0 commit comments

Comments
 (0)