Skip to content

Commit c4ae841

Browse files
committed
Merge branch 'io_uring-7.0' into for-next
* io_uring-7.0: io_uring/kbuf: propagate BUF_MORE through early buffer commit path io_uring/kbuf: fix missing BUF_MORE for incremental buffers at EOF
2 parents 27c7fa5 + 418eab7 commit c4ae841

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

include/linux/io_uring_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ enum {
557557
REQ_F_BL_NO_RECYCLE_BIT,
558558
REQ_F_BUFFERS_COMMIT_BIT,
559559
REQ_F_BUF_NODE_BIT,
560+
REQ_F_BUF_MORE_BIT,
560561
REQ_F_HAS_METADATA_BIT,
561562
REQ_F_IMPORT_BUFFER_BIT,
562563
REQ_F_SQE_COPIED_BIT,
@@ -643,6 +644,8 @@ enum {
643644
REQ_F_BUFFERS_COMMIT = IO_REQ_FLAG(REQ_F_BUFFERS_COMMIT_BIT),
644645
/* buf node is valid */
645646
REQ_F_BUF_NODE = IO_REQ_FLAG(REQ_F_BUF_NODE_BIT),
647+
/* incremental buffer consumption, more space available */
648+
REQ_F_BUF_MORE = IO_REQ_FLAG(REQ_F_BUF_MORE_BIT),
646649
/* request has read/write metadata assigned */
647650
REQ_F_HAS_METADATA = IO_REQ_FLAG(REQ_F_HAS_METADATA_BIT),
648651
/*

io_uring/kbuf.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ struct io_provide_buf {
3434

3535
static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
3636
{
37+
/* No data consumed, return false early to avoid consuming the buffer */
38+
if (!len)
39+
return false;
40+
3741
while (len) {
3842
struct io_uring_buf *buf;
3943
u32 buf_len, this_len;
@@ -212,7 +216,8 @@ static struct io_br_sel io_ring_buffer_select(struct io_kiocb *req, size_t *len,
212216
sel.addr = u64_to_user_ptr(READ_ONCE(buf->addr));
213217

214218
if (io_should_commit(req, issue_flags)) {
215-
io_kbuf_commit(req, sel.buf_list, *len, 1);
219+
if (!io_kbuf_commit(req, sel.buf_list, *len, 1))
220+
req->flags |= REQ_F_BUF_MORE;
216221
sel.buf_list = NULL;
217222
}
218223
return sel;
@@ -345,7 +350,8 @@ int io_buffers_select(struct io_kiocb *req, struct buf_sel_arg *arg,
345350
*/
346351
if (ret > 0) {
347352
req->flags |= REQ_F_BUFFERS_COMMIT | REQ_F_BL_NO_RECYCLE;
348-
io_kbuf_commit(req, sel->buf_list, arg->out_len, ret);
353+
if (!io_kbuf_commit(req, sel->buf_list, arg->out_len, ret))
354+
req->flags |= REQ_F_BUF_MORE;
349355
}
350356
} else {
351357
ret = io_provided_buffers_select(req, &arg->out_len, sel->buf_list, arg->iovs);
@@ -391,8 +397,10 @@ static inline bool __io_put_kbuf_ring(struct io_kiocb *req,
391397

392398
if (bl)
393399
ret = io_kbuf_commit(req, bl, len, nr);
400+
if (ret && (req->flags & REQ_F_BUF_MORE))
401+
ret = false;
394402

395-
req->flags &= ~REQ_F_BUFFER_RING;
403+
req->flags &= ~(REQ_F_BUFFER_RING | REQ_F_BUF_MORE);
396404
return ret;
397405
}
398406

0 commit comments

Comments
 (0)