• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Description: IOPOLL with overflow test case
4  */
5 #include <errno.h>
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <fcntl.h>
11 #include <sys/types.h>
12 #include <poll.h>
13 #include <sys/eventfd.h>
14 #include <sys/resource.h>
15 #include "helpers.h"
16 #include "liburing.h"
17 #include "../src/syscall.h"
18 
19 #define FILE_SIZE	(128 * 1024)
20 #define BS		4096
21 #define BUFFERS		(FILE_SIZE / BS)
22 
23 static struct iovec *vecs;
24 
test(struct io_uring * ring,int fd)25 static int test(struct io_uring *ring, int fd)
26 {
27 	struct io_uring_sqe *sqe;
28 	int i, j, ret;
29 	loff_t off;
30 
31 	off = FILE_SIZE - BS;
32 	for (j = 0; j < 8; j++) {
33 		for (i = 0; i < BUFFERS; i++) {
34 			sqe = io_uring_get_sqe(ring);
35 			io_uring_prep_read(sqe, fd, vecs[i].iov_base,
36 						vecs[i].iov_len, off);
37 			if (!off)
38 				off = FILE_SIZE - BS;
39 			else
40 				off -= BS;
41 		}
42 		ret = io_uring_submit(ring);
43 		if (ret != BUFFERS) {
44 			fprintf(stderr, "submitted %d\n", ret);
45 			return T_EXIT_FAIL;
46 		}
47 	}
48 
49 	sleep(1);
50 
51 	ret = __sys_io_uring_enter(ring->ring_fd, 0, BUFFERS * 8,
52 					IORING_ENTER_GETEVENTS, NULL);
53 
54 	for (i = 0; i < BUFFERS * 8; i++) {
55 		struct io_uring_cqe *cqe;
56 
57 		ret = io_uring_wait_cqe(ring, &cqe);
58 		if (ret) {
59 			fprintf(stderr, "wait=%d\n", ret);
60 			return T_EXIT_FAIL;
61 		}
62 		io_uring_cqe_seen(ring, cqe);
63 	}
64 
65 	return T_EXIT_PASS;
66 }
67 
main(int argc,char * argv[])68 int main(int argc, char *argv[])
69 {
70 	struct io_uring_params p = { };
71 	struct io_uring ring;
72 	char buf[256];
73 	char *fname;
74 	int ret, fd;
75 
76 	p.flags = IORING_SETUP_IOPOLL | IORING_SETUP_CQSIZE;
77 	p.cq_entries = 64;
78 	ret = t_create_ring_params(64, &ring, &p);
79 	if (ret == T_SETUP_SKIP)
80 		return 0;
81 	if (ret != T_SETUP_OK) {
82 		fprintf(stderr, "ring create failed: %d\n", ret);
83 		return 1;
84 	}
85 
86 	if (argc > 1) {
87 		fname = argv[1];
88 	} else {
89 		srand((unsigned)time(NULL));
90 		snprintf(buf, sizeof(buf), ".basic-rw-%u-%u",
91 			(unsigned)rand(), (unsigned)getpid());
92 		fname = buf;
93 		t_create_file(fname, FILE_SIZE);
94 	}
95 
96 	fd = open(fname, O_RDONLY | O_DIRECT);
97 	if (fd < 0) {
98 		if (errno == EINVAL || errno == EACCES || errno == EPERM) {
99 			if (fname != argv[1])
100 				unlink(fname);
101 			return T_EXIT_SKIP;
102 		}
103 		perror("open");
104 		goto err;
105 	}
106 
107 	vecs = t_create_buffers(BUFFERS, BS);
108 
109 	ret = test(&ring, fd);
110 
111 	if (fname != argv[1])
112 		unlink(fname);
113 	return ret;
114 err:
115 	if (fname != argv[1])
116 		unlink(fname);
117 	return T_EXIT_FAIL;
118 }
119