summaryrefslogtreecommitdiff
path: root/fs/io_uring.c
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2020-07-13 22:59:20 +0300
committerJens Axboe <axboe@kernel.dk>2020-07-24 12:55:44 -0600
commit252917c30f551e8e4377faac81d7fcf8e9629df1 (patch)
tree938627f73a8b73ee2aef2c2dfa59d63db7da13c2 /fs/io_uring.c
parentc3e330a493740a2a8312dcb7b1cffceaec7f619a (diff)
downloadlwn-252917c30f551e8e4377faac81d7fcf8e9629df1.tar.gz
lwn-252917c30f551e8e4377faac81d7fcf8e9629df1.zip
io_uring: follow **iovec idiom in io_import_iovec
As for import_iovec(), return !=NULL iovec from io_import_iovec() only when it should be freed. That includes returning NULL when iovec is already in req->io, because it should be deallocated by other means, e.g. inside op handler. After io_setup_async_rw() local iovec to ->io, just mark it NULL, to follow the idea in io_{read,write} as well. That's easier to follow, and especially useful if we want to reuse per-op space for completion data. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> [axboe: only call kfree() on non-NULL pointer] Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r--fs/io_uring.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 31466bcd833e..64ae5b681c62 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2740,10 +2740,8 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
if (req->io) {
struct io_async_rw *iorw = &req->io->rw;
- *iovec = iorw->iov;
- iov_iter_init(iter, rw, *iovec, iorw->nr_segs, iorw->size);
- if (iorw->iov == iorw->fast_iov)
- *iovec = NULL;
+ iov_iter_init(iter, rw, iorw->iov, iorw->nr_segs, iorw->size);
+ *iovec = NULL;
return iorw->size;
}
@@ -3026,6 +3024,8 @@ copy_iov:
inline_vecs, &iter);
if (ret)
goto out_free;
+ /* it's copied and will be cleaned with ->io */
+ iovec = NULL;
/* if we can retry, do so with the callbacks armed */
if (io_rw_should_retry(req)) {
ret2 = io_iter_do_read(req, &iter);
@@ -3041,7 +3041,7 @@ copy_iov:
}
}
out_free:
- if (!(req->flags & REQ_F_NEED_CLEANUP))
+ if (iovec)
kfree(iovec);
return ret;
}
@@ -3143,11 +3143,13 @@ copy_iov:
inline_vecs, &iter);
if (ret)
goto out_free;
+ /* it's copied and will be cleaned with ->io */
+ iovec = NULL;
return -EAGAIN;
}
}
out_free:
- if (!(req->flags & REQ_F_NEED_CLEANUP))
+ if (iovec)
kfree(iovec);
return ret;
}