xref: /aosp_15_r20/external/liburing/examples/io_uring-test.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Simple app that demonstrates how to setup an io_uring interface,
4  * submit and complete IO against it, and then tear it down.
5  *
6  * gcc -Wall -O2 -D_GNU_SOURCE -o io_uring-test io_uring-test.c -luring
7  */
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include "liburing.h"
16 
17 #define QD	4
18 
main(int argc,char * argv[])19 int main(int argc, char *argv[])
20 {
21 	struct io_uring ring;
22 	int i, fd, ret, pending, done;
23 	struct io_uring_sqe *sqe;
24 	struct io_uring_cqe *cqe;
25 	struct iovec *iovecs;
26 	struct stat sb;
27 	ssize_t fsize;
28 	off_t offset;
29 	void *buf;
30 
31 	if (argc < 2) {
32 		printf("%s: file\n", argv[0]);
33 		return 1;
34 	}
35 
36 	ret = io_uring_queue_init(QD, &ring, 0);
37 	if (ret < 0) {
38 		fprintf(stderr, "queue_init: %s\n", strerror(-ret));
39 		return 1;
40 	}
41 
42 	fd = open(argv[1], O_RDONLY | O_DIRECT);
43 	if (fd < 0) {
44 		perror("open");
45 		return 1;
46 	}
47 
48 	if (fstat(fd, &sb) < 0) {
49 		perror("fstat");
50 		return 1;
51 	}
52 
53 	fsize = 0;
54 	iovecs = calloc(QD, sizeof(struct iovec));
55 	for (i = 0; i < QD; i++) {
56 		if (posix_memalign(&buf, 4096, 4096))
57 			return 1;
58 		iovecs[i].iov_base = buf;
59 		iovecs[i].iov_len = 4096;
60 		fsize += 4096;
61 	}
62 
63 	offset = 0;
64 	i = 0;
65 	do {
66 		sqe = io_uring_get_sqe(&ring);
67 		if (!sqe)
68 			break;
69 		io_uring_prep_readv(sqe, fd, &iovecs[i], 1, offset);
70 		offset += iovecs[i].iov_len;
71 		i++;
72 		if (offset > sb.st_size)
73 			break;
74 	} while (1);
75 
76 	ret = io_uring_submit(&ring);
77 	if (ret < 0) {
78 		fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret));
79 		return 1;
80 	} else if (ret != i) {
81 		fprintf(stderr, "io_uring_submit submitted less %d\n", ret);
82 		return 1;
83 	}
84 
85 	done = 0;
86 	pending = ret;
87 	fsize = 0;
88 	for (i = 0; i < pending; i++) {
89 		ret = io_uring_wait_cqe(&ring, &cqe);
90 		if (ret < 0) {
91 			fprintf(stderr, "io_uring_wait_cqe: %s\n", strerror(-ret));
92 			return 1;
93 		}
94 
95 		done++;
96 		ret = 0;
97 		if (cqe->res != 4096 && cqe->res + fsize != sb.st_size) {
98 			fprintf(stderr, "ret=%d, wanted 4096\n", cqe->res);
99 			ret = 1;
100 		}
101 		fsize += cqe->res;
102 		io_uring_cqe_seen(&ring, cqe);
103 		if (ret)
104 			break;
105 	}
106 
107 	printf("Submitted=%d, completed=%d, bytes=%lu\n", pending, done,
108 						(unsigned long) fsize);
109 	close(fd);
110 	io_uring_queue_exit(&ring);
111 	return 0;
112 }
113