diff options
author | Jens Axboe <axboe@kernel.dk> | 2019-05-15 14:07:52 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-05-15 14:07:52 -0600 |
commit | 5c6e5d27451267c650d88a70a0f49563383d40c5 (patch) | |
tree | 9eb745324494c7dd62a86326844d537c51116ca8 /examples | |
parent | 7e8902e14c1e684c03d44a7357928246b96b55bb (diff) |
examples/link-cp: improvements
Add short read requeue and abort on error.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'examples')
-rw-r--r-- | examples/link-cp.c | 41 |
1 files 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--; } } |