From 5c6e5d27451267c650d88a70a0f49563383d40c5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 15 May 2019 14:07:52 -0600 Subject: examples/link-cp: improvements Add short read requeue and abort on error. Signed-off-by: Jens Axboe --- examples/link-cp.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/examples/link-cp.c b/examples/link-cp.c index 9ac4658..8f29956 100644 --- a/examples/link-cp.c +++ b/examples/link-cp.c @@ -19,10 +19,13 @@ #define BS (32*1024) struct io_data { + size_t offset; + int index; struct iovec iov; }; static int infd, outfd; +static unsigned inflight; static int setup_context(unsigned entries, struct io_uring *ring) { @@ -59,36 +62,48 @@ static int get_file_size(int fd, off_t *size) return -1; } -static int queue_rw_pair(struct io_uring *ring, off_t size, off_t offset) +static void queue_rw_pair(struct io_uring *ring, off_t size, off_t offset) { struct io_uring_sqe *sqe; struct io_data *data; data = malloc(size + sizeof(*data)); + data->index = 0; + data->offset = offset; data->iov.iov_base = data + 1; data->iov.iov_len = size; sqe = io_uring_get_sqe(ring); io_uring_prep_readv(sqe, infd, &data->iov, 1, offset); sqe->flags |= IOSQE_IO_LINK; + io_uring_sqe_set_data(sqe, data); sqe = io_uring_get_sqe(ring); io_uring_prep_writev(sqe, outfd, &data->iov, 1, offset); io_uring_sqe_set_data(sqe, data); - return 0; } -static void handle_cqe(struct io_uring *ring, struct io_uring_cqe *cqe) +static int handle_cqe(struct io_uring *ring, struct io_uring_cqe *cqe) { - struct io_data *data; + struct io_data *data = io_uring_cqe_get_data(cqe); + int ret = 0; + + data->index++; - if (cqe->res < 0) - printf("cqe error: %s\n", strerror(cqe->res)); + if (cqe->res < 0) { + if (cqe->res == -ECANCELED) { + queue_rw_pair(ring, BS, data->offset); + inflight += 2; + } else { + printf("cqe error: %s\n", strerror(cqe->res)); + ret = 1; + } + } - data = io_uring_cqe_get_data(cqe); - if (data) + if (data->index == 2) free(data); io_uring_cqe_seen(ring, cqe); + return ret; } static int copy_file(struct io_uring *ring, off_t insize) @@ -96,10 +111,8 @@ static int copy_file(struct io_uring *ring, off_t insize) struct io_uring_cqe *cqe; size_t this_size; off_t offset; - int inflight; offset = 0; - inflight = 0; while (insize) { int has_inflight = inflight; int depth; @@ -125,8 +138,12 @@ static int copy_file(struct io_uring *ring, off_t insize) int ret; ret = io_uring_wait_cqe(ring, &cqe); - assert(ret >= 0); - handle_cqe(ring, cqe); + if (ret < 0) { + printf("wait cqe: %s\n", strerror(ret)); + return 1; + } + if (handle_cqe(ring, cqe)) + return 1; inflight--; } } -- cgit