Skip to content

Commit 9adbd45

Browse files
committed
io_uring: add and use struct io_rw for read/writes
Put the kiocb in struct io_rw, and add the addr/len for the request as well. Use the kiocb->private field for the buffer index for fixed reads and writes. Any use of kiocb->ki_filp is flipped to req->file. It's the same thing, and less confusing. Signed-off-by: Jens Axboe <[email protected]>
1 parent d55e5f5 commit 9adbd45

File tree

1 file changed

+50
-46
lines changed

1 file changed

+50
-46
lines changed

fs/io_uring.c

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,13 @@ struct io_timeout {
332332
int flags;
333333
};
334334

335+
struct io_rw {
336+
/* NOTE: kiocb has the file as the first member, so don't do it here */
337+
struct kiocb kiocb;
338+
u64 addr;
339+
u64 len;
340+
};
341+
335342
struct io_async_connect {
336343
struct sockaddr_storage address;
337344
};
@@ -369,7 +376,7 @@ struct io_async_ctx {
369376
struct io_kiocb {
370377
union {
371378
struct file *file;
372-
struct kiocb rw;
379+
struct io_rw rw;
373380
struct io_poll_iocb poll;
374381
struct io_accept accept;
375382
struct io_sync sync;
@@ -1180,7 +1187,7 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events,
11801187

11811188
ret = 0;
11821189
list_for_each_entry_safe(req, tmp, &ctx->poll_list, list) {
1183-
struct kiocb *kiocb = &req->rw;
1190+
struct kiocb *kiocb = &req->rw.kiocb;
11841191

11851192
/*
11861193
* Move completed entries to our local list. If we find a
@@ -1335,7 +1342,7 @@ static inline void req_set_fail_links(struct io_kiocb *req)
13351342

13361343
static void io_complete_rw_common(struct kiocb *kiocb, long res)
13371344
{
1338-
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw);
1345+
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
13391346

13401347
if (kiocb->ki_flags & IOCB_WRITE)
13411348
kiocb_end_write(req);
@@ -1347,15 +1354,15 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res)
13471354

13481355
static void io_complete_rw(struct kiocb *kiocb, long res, long res2)
13491356
{
1350-
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw);
1357+
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
13511358

13521359
io_complete_rw_common(kiocb, res);
13531360
io_put_req(req);
13541361
}
13551362

13561363
static struct io_kiocb *__io_complete_rw(struct kiocb *kiocb, long res)
13571364
{
1358-
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw);
1365+
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
13591366
struct io_kiocb *nxt = NULL;
13601367

13611368
io_complete_rw_common(kiocb, res);
@@ -1366,7 +1373,7 @@ static struct io_kiocb *__io_complete_rw(struct kiocb *kiocb, long res)
13661373

13671374
static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)
13681375
{
1369-
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw);
1376+
struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
13701377

13711378
if (kiocb->ki_flags & IOCB_WRITE)
13721379
kiocb_end_write(req);
@@ -1400,7 +1407,7 @@ static void io_iopoll_req_issued(struct io_kiocb *req)
14001407

14011408
list_req = list_first_entry(&ctx->poll_list, struct io_kiocb,
14021409
list);
1403-
if (list_req->rw.ki_filp != req->rw.ki_filp)
1410+
if (list_req->file != req->file)
14041411
ctx->poll_multi_file = true;
14051412
}
14061413

@@ -1475,7 +1482,7 @@ static int io_prep_rw(struct io_kiocb *req, bool force_nonblock)
14751482
{
14761483
const struct io_uring_sqe *sqe = req->sqe;
14771484
struct io_ring_ctx *ctx = req->ctx;
1478-
struct kiocb *kiocb = &req->rw;
1485+
struct kiocb *kiocb = &req->rw.kiocb;
14791486
unsigned ioprio;
14801487
int ret;
14811488

@@ -1524,6 +1531,12 @@ static int io_prep_rw(struct io_kiocb *req, bool force_nonblock)
15241531
return -EINVAL;
15251532
kiocb->ki_complete = io_complete_rw;
15261533
}
1534+
1535+
req->rw.addr = READ_ONCE(req->sqe->addr);
1536+
req->rw.len = READ_ONCE(req->sqe->len);
1537+
/* we own ->private, reuse it for the buffer index */
1538+
req->rw.kiocb.private = (void *) (unsigned long)
1539+
READ_ONCE(req->sqe->buf_index);
15271540
return 0;
15281541
}
15291542

@@ -1557,11 +1570,11 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret, struct io_kiocb **nxt,
15571570
io_rw_done(kiocb, ret);
15581571
}
15591572

1560-
static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw,
1561-
const struct io_uring_sqe *sqe,
1573+
static ssize_t io_import_fixed(struct io_kiocb *req, int rw,
15621574
struct iov_iter *iter)
15631575
{
1564-
size_t len = READ_ONCE(sqe->len);
1576+
struct io_ring_ctx *ctx = req->ctx;
1577+
size_t len = req->rw.len;
15651578
struct io_mapped_ubuf *imu;
15661579
unsigned index, buf_index;
15671580
size_t offset;
@@ -1571,13 +1584,13 @@ static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw,
15711584
if (unlikely(!ctx->user_bufs))
15721585
return -EFAULT;
15731586

1574-
buf_index = READ_ONCE(sqe->buf_index);
1587+
buf_index = (unsigned long) req->rw.kiocb.private;
15751588
if (unlikely(buf_index >= ctx->nr_user_bufs))
15761589
return -EFAULT;
15771590

15781591
index = array_index_nospec(buf_index, ctx->nr_user_bufs);
15791592
imu = &ctx->user_bufs[index];
1580-
buf_addr = READ_ONCE(sqe->addr);
1593+
buf_addr = req->rw.addr;
15811594

15821595
/* overflow */
15831596
if (buf_addr + len < buf_addr)
@@ -1634,25 +1647,20 @@ static ssize_t io_import_fixed(struct io_ring_ctx *ctx, int rw,
16341647
static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
16351648
struct iovec **iovec, struct iov_iter *iter)
16361649
{
1637-
const struct io_uring_sqe *sqe = req->sqe;
1638-
void __user *buf = u64_to_user_ptr(READ_ONCE(sqe->addr));
1639-
size_t sqe_len = READ_ONCE(sqe->len);
1650+
void __user *buf = u64_to_user_ptr(req->rw.addr);
1651+
size_t sqe_len = req->rw.len;
16401652
u8 opcode;
16411653

1642-
/*
1643-
* We're reading ->opcode for the second time, but the first read
1644-
* doesn't care whether it's _FIXED or not, so it doesn't matter
1645-
* whether ->opcode changes concurrently. The first read does care
1646-
* about whether it is a READ or a WRITE, so we don't trust this read
1647-
* for that purpose and instead let the caller pass in the read/write
1648-
* flag.
1649-
*/
16501654
opcode = req->opcode;
16511655
if (opcode == IORING_OP_READ_FIXED || opcode == IORING_OP_WRITE_FIXED) {
16521656
*iovec = NULL;
1653-
return io_import_fixed(req->ctx, rw, sqe, iter);
1657+
return io_import_fixed(req, rw, iter);
16541658
}
16551659

1660+
/* buffer index only valid with fixed read/write */
1661+
if (req->rw.kiocb.private)
1662+
return -EINVAL;
1663+
16561664
if (req->io) {
16571665
struct io_async_rw *iorw = &req->io->rw;
16581666

@@ -1801,9 +1809,8 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
18011809
bool force_nonblock)
18021810
{
18031811
struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
1804-
struct kiocb *kiocb = &req->rw;
1812+
struct kiocb *kiocb = &req->rw.kiocb;
18051813
struct iov_iter iter;
1806-
struct file *file;
18071814
size_t iov_count;
18081815
ssize_t io_size, ret;
18091816

@@ -1819,9 +1826,8 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
18191826

18201827
/* Ensure we clear previously set non-block flag */
18211828
if (!force_nonblock)
1822-
req->rw.ki_flags &= ~IOCB_NOWAIT;
1829+
req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT;
18231830

1824-
file = req->file;
18251831
io_size = ret;
18261832
if (req->flags & REQ_F_LINK)
18271833
req->result = io_size;
@@ -1830,20 +1836,20 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
18301836
* If the file doesn't support async, mark it as REQ_F_MUST_PUNT so
18311837
* we know to async punt it even if it was opened O_NONBLOCK
18321838
*/
1833-
if (force_nonblock && !io_file_supports_async(file)) {
1839+
if (force_nonblock && !io_file_supports_async(req->file)) {
18341840
req->flags |= REQ_F_MUST_PUNT;
18351841
goto copy_iov;
18361842
}
18371843

18381844
iov_count = iov_iter_count(&iter);
1839-
ret = rw_verify_area(READ, file, &kiocb->ki_pos, iov_count);
1845+
ret = rw_verify_area(READ, req->file, &kiocb->ki_pos, iov_count);
18401846
if (!ret) {
18411847
ssize_t ret2;
18421848

1843-
if (file->f_op->read_iter)
1844-
ret2 = call_read_iter(file, kiocb, &iter);
1849+
if (req->file->f_op->read_iter)
1850+
ret2 = call_read_iter(req->file, kiocb, &iter);
18451851
else
1846-
ret2 = loop_rw_iter(READ, file, kiocb, &iter);
1852+
ret2 = loop_rw_iter(READ, req->file, kiocb, &iter);
18471853

18481854
/*
18491855
* In case of a short read, punt to async. This can happen
@@ -1894,9 +1900,8 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
18941900
bool force_nonblock)
18951901
{
18961902
struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
1897-
struct kiocb *kiocb = &req->rw;
1903+
struct kiocb *kiocb = &req->rw.kiocb;
18981904
struct iov_iter iter;
1899-
struct file *file;
19001905
size_t iov_count;
19011906
ssize_t ret, io_size;
19021907

@@ -1912,9 +1917,8 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
19121917

19131918
/* Ensure we clear previously set non-block flag */
19141919
if (!force_nonblock)
1915-
req->rw.ki_flags &= ~IOCB_NOWAIT;
1920+
req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT;
19161921

1917-
file = kiocb->ki_filp;
19181922
io_size = ret;
19191923
if (req->flags & REQ_F_LINK)
19201924
req->result = io_size;
@@ -1934,7 +1938,7 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
19341938
goto copy_iov;
19351939

19361940
iov_count = iov_iter_count(&iter);
1937-
ret = rw_verify_area(WRITE, file, &kiocb->ki_pos, iov_count);
1941+
ret = rw_verify_area(WRITE, req->file, &kiocb->ki_pos, iov_count);
19381942
if (!ret) {
19391943
ssize_t ret2;
19401944

@@ -1946,17 +1950,17 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
19461950
* we return to userspace.
19471951
*/
19481952
if (req->flags & REQ_F_ISREG) {
1949-
__sb_start_write(file_inode(file)->i_sb,
1953+
__sb_start_write(file_inode(req->file)->i_sb,
19501954
SB_FREEZE_WRITE, true);
1951-
__sb_writers_release(file_inode(file)->i_sb,
1955+
__sb_writers_release(file_inode(req->file)->i_sb,
19521956
SB_FREEZE_WRITE);
19531957
}
19541958
kiocb->ki_flags |= IOCB_WRITE;
19551959

1956-
if (file->f_op->write_iter)
1957-
ret2 = call_write_iter(file, kiocb, &iter);
1960+
if (req->file->f_op->write_iter)
1961+
ret2 = call_write_iter(req->file, kiocb, &iter);
19581962
else
1959-
ret2 = loop_rw_iter(WRITE, file, kiocb, &iter);
1963+
ret2 = loop_rw_iter(WRITE, req->file, kiocb, &iter);
19601964
if (!force_nonblock || ret2 != -EAGAIN) {
19611965
kiocb_done(kiocb, ret2, nxt, req->in_async);
19621966
} else {
@@ -2036,7 +2040,7 @@ static void io_fsync_finish(struct io_wq_work **workptr)
20362040
if (io_req_cancelled(req))
20372041
return;
20382042

2039-
ret = vfs_fsync_range(req->rw.ki_filp, req->sync.off,
2043+
ret = vfs_fsync_range(req->file, req->sync.off,
20402044
end > 0 ? end : LLONG_MAX,
20412045
req->sync.flags & IORING_FSYNC_DATASYNC);
20422046
if (ret < 0)
@@ -2102,7 +2106,7 @@ static void io_sync_file_range_finish(struct io_wq_work **workptr)
21022106
if (io_req_cancelled(req))
21032107
return;
21042108

2105-
ret = sync_file_range(req->rw.ki_filp, req->sync.off, req->sync.len,
2109+
ret = sync_file_range(req->file, req->sync.off, req->sync.len,
21062110
req->sync.flags);
21072111
if (ret < 0)
21082112
req_set_fail_links(req);

0 commit comments

Comments
 (0)