| 41 | } |
| 42 | |
| 43 | static int test_read(struct io_uring *ring, bool async, int blocksize) |
| 44 | { |
| 45 | int ret, fd, i; |
| 46 | bool done = false; |
| 47 | struct io_uring_sqe *sqe; |
| 48 | struct io_uring_cqe *cqe; |
| 49 | loff_t current, expected = 0; |
| 50 | int count_ok; |
| 51 | int count_0 = 0, count_1 = 0; |
| 52 | unsigned char buff[QUEUE_SIZE * blocksize]; |
| 53 | unsigned char reordered[QUEUE_SIZE * blocksize]; |
| 54 | |
| 55 | memset(buff, 0, QUEUE_SIZE * blocksize); |
| 56 | memset(reordered, 0, QUEUE_SIZE * blocksize); |
| 57 | |
| 58 | create_file(".test_fpos_read", FILE_SIZE); |
| 59 | fd = open(".test_fpos_read", O_RDONLY); |
| 60 | unlink(".test_fpos_read"); |
| 61 | assert(fd >= 0); |
| 62 | |
| 63 | while (!done) { |
| 64 | for (i = 0; i < QUEUE_SIZE; ++i) { |
| 65 | sqe = io_uring_get_sqe(ring); |
| 66 | if (!sqe) { |
| 67 | fprintf(stderr, "no sqe\n"); |
| 68 | return -1; |
| 69 | } |
| 70 | io_uring_prep_read(sqe, fd, |
| 71 | buff + i * blocksize, |
| 72 | blocksize, -1); |
| 73 | sqe->user_data = i; |
| 74 | if (async) |
| 75 | sqe->flags |= IOSQE_ASYNC; |
| 76 | if (i != QUEUE_SIZE - 1) |
| 77 | sqe->flags |= IOSQE_IO_LINK; |
| 78 | } |
| 79 | ret = io_uring_submit_and_wait(ring, QUEUE_SIZE); |
| 80 | if (ret != QUEUE_SIZE) { |
| 81 | fprintf(stderr, "submit failed: %d\n", ret); |
| 82 | return 1; |
| 83 | } |
| 84 | count_ok = 0; |
| 85 | for (i = 0; i < QUEUE_SIZE; ++i) { |
| 86 | int res; |
| 87 | |
| 88 | ret = io_uring_peek_cqe(ring, &cqe); |
| 89 | if (ret) { |
| 90 | fprintf(stderr, "peek failed: %d\n", ret); |
| 91 | return ret; |
| 92 | } |
| 93 | assert(cqe->user_data < QUEUE_SIZE); |
| 94 | memcpy(reordered + count_ok, |
| 95 | buff + cqe->user_data * blocksize, blocksize); |
| 96 | res = cqe->res; |
| 97 | io_uring_cqe_seen(ring, cqe); |
| 98 | if (res == 0) { |
| 99 | done = true; |
| 100 | } else if (res == -ECANCELED) { |
no test coverage detected