1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Test fixed buffer merging/skipping
4 *
5 * Taken from: https://github.com/axboe/liburing/issues/994
6 *
7 */
8 #include <stdio.h>
9 #include <string.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13
14 #include "liburing.h"
15 #include "helpers.h"
16
main(int argc,char * argv[])17 int main(int argc, char *argv[])
18 {
19 int ret, i, fd, initial_offset = 4096, num_requests = 3;
20 struct io_uring ring;
21 struct io_uring_sqe *sqe;
22 struct io_uring_cqe *cqe;
23 struct iovec iov;
24 char *buffer, *to_free;
25 unsigned head;
26 char filename[64];
27
28 ret = io_uring_queue_init(4, &ring, 0);
29 if (ret) {
30 fprintf(stderr, "queue_init: %d\n", ret);
31 return T_EXIT_FAIL;
32 }
33
34 sprintf(filename, ".fixed-buf-%d", getpid());
35 t_create_file(filename, 4 * 4096);
36
37 fd = open(filename, O_RDONLY | O_DIRECT, 0644);
38 if (fd < 0) {
39 if (errno == EINVAL) {
40 unlink(filename);
41 return T_EXIT_SKIP;
42 }
43 perror("open");
44 goto err_unlink;
45 }
46
47 to_free = buffer = aligned_alloc(4096, 128 * 4096);
48 if (!buffer) {
49 perror("aligned_alloc");
50 goto err_unlink;
51 }
52
53 /* Register buffer */
54 iov.iov_base = buffer;
55 iov.iov_len = 128 * 4096;
56
57 ret = io_uring_register_buffers(&ring, &iov, 1);
58 if (ret) {
59 fprintf(stderr, "buf register: %d\n", ret);
60 goto err_unlink;
61 }
62
63 /* Prepare read requests */
64 buffer += initial_offset;
65 for (i = 0; i < num_requests; i++) {
66 sqe = io_uring_get_sqe(&ring);
67 io_uring_prep_read_fixed(sqe, fd, buffer, 4096, 4096 * i, 0);
68 buffer += 4096;
69 }
70
71 /* Submit requests and reap completions */
72 ret = io_uring_submit_and_wait(&ring, num_requests);
73 if (ret != num_requests) {
74 fprintf(stderr, "Submit and wait: %d\n", ret);
75 goto err_unlink;
76 }
77
78 i = 0;
79 io_uring_for_each_cqe(&ring, head, cqe) {
80 if (cqe->res != 4096) {
81 fprintf(stderr, "cqe: %d\n", cqe->res);
82 goto err_unlink;
83 }
84 i++;
85 }
86
87 if (i != num_requests) {
88 fprintf(stderr, "Got %d completions\n", i);
89 goto err_unlink;
90 }
91
92 io_uring_cq_advance(&ring, i);
93 io_uring_queue_exit(&ring);
94 close(fd);
95 free(to_free);
96 unlink(filename);
97 return T_EXIT_PASS;
98 err_unlink:
99 unlink(filename);
100 return T_EXIT_FAIL;
101 }
102