]> git.proxmox.com Git - ceph.git/blob - ceph/qa/workunits/direct_io/test_sync_io.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / qa / workunits / direct_io / test_sync_io.c
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <inttypes.h>
7 #include <linux/types.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/ioctl.h>
11 #include <errno.h>
12
13 //#include "../client/ioctl.h"
14
15 #include <linux/ioctl.h>
16 #define CEPH_IOCTL_MAGIC 0x97
17 #define CEPH_IOC_SYNCIO _IO(CEPH_IOCTL_MAGIC, 5)
18
19 void write_pattern()
20 {
21 printf("writing pattern\n");
22
23 uint64_t i;
24 int r;
25
26 int fd = open("foo", O_CREAT|O_WRONLY, 0644);
27 if (fd < 0) {
28 r = errno;
29 printf("write_pattern: error: open() failed with: %d (%s)\n", r, strerror(r));
30 exit(r);
31 }
32 for (i=0; i<1048576 * sizeof(i); i += sizeof(i)) {
33 r = write(fd, &i, sizeof(i));
34 if (r == -1) {
35 r = errno;
36 printf("write_pattern: error: write() failed with: %d (%s)\n", r, strerror(r));
37 break;
38 }
39 }
40
41 close(fd);
42 }
43
44 int verify_pattern(char *buf, size_t len, uint64_t off)
45 {
46 size_t i;
47
48 for (i = 0; i < len; i += sizeof(uint64_t)) {
49 uint64_t expected = i + off;
50 uint64_t actual = *(uint64_t*)(buf + i);
51 if (expected != actual) {
52 printf("error: offset %llu had %llu\n", (unsigned long long)expected,
53 (unsigned long long)actual);
54 exit(1);
55 }
56 }
57 return 0;
58 }
59
60 void generate_pattern(void *buf, size_t len, uint64_t offset)
61 {
62 uint64_t *v = buf;
63 size_t i;
64
65 for (i=0; i<len / sizeof(v); i++)
66 v[i] = i * sizeof(v) + offset;
67 verify_pattern(buf, len, offset);
68 }
69
70 int read_file(int buf_align, uint64_t offset, int len, int direct) {
71
72 printf("read_file buf_align %d offset %llu len %d\n", buf_align,
73 (unsigned long long)offset, len);
74 void *rawbuf;
75 int r;
76 int flags;
77 int err = 0;
78
79 if(direct)
80 flags = O_RDONLY|O_DIRECT;
81 else
82 flags = O_RDONLY;
83
84 int fd = open("foo", flags);
85 if (fd < 0) {
86 err = errno;
87 printf("read_file: error: open() failed with: %d (%s)\n", err, strerror(err));
88 exit(err);
89 }
90
91 if (!direct)
92 ioctl(fd, CEPH_IOC_SYNCIO);
93
94 if ((r = posix_memalign(&rawbuf, 4096, len + buf_align)) != 0) {
95 printf("read_file: error: posix_memalign failed with %d", r);
96 close(fd);
97 exit (r);
98 }
99
100 void *buf = (char *)rawbuf + buf_align;
101 memset(buf, 0, len);
102 r = pread(fd, buf, len, offset);
103 if (r == -1) {
104 err = errno;
105 printf("read_file: error: pread() failed with: %d (%s)\n", err, strerror(err));
106 goto out;
107 }
108 r = verify_pattern(buf, len, offset);
109
110 out:
111 close(fd);
112 free(rawbuf);
113 return r;
114 }
115
116 int read_direct(int buf_align, uint64_t offset, int len)
117 {
118 printf("read_direct buf_align %d offset %llu len %d\n", buf_align,
119 (unsigned long long)offset, len);
120 return read_file(buf_align, offset, len, 1);
121 }
122
123 int read_sync(int buf_align, uint64_t offset, int len)
124 {
125 printf("read_sync buf_align %d offset %llu len %d\n", buf_align,
126 (unsigned long long)offset, len);
127 return read_file(buf_align, offset, len, 0);
128 }
129
130 int write_file(int buf_align, uint64_t offset, int len, int direct)
131 {
132 printf("write_file buf_align %d offset %llu len %d\n", buf_align,
133 (unsigned long long)offset, len);
134 void *rawbuf;
135 int r;
136 int err = 0;
137 int flags;
138 if (direct)
139 flags = O_WRONLY|O_DIRECT|O_CREAT;
140 else
141 flags = O_WRONLY|O_CREAT;
142
143 int fd = open("foo", flags, 0644);
144 if (fd < 0) {
145 int err = errno;
146 printf("write_file: error: open() failed with: %d (%s)\n", err, strerror(err));
147 exit(err);
148 }
149
150 if ((r = posix_memalign(&rawbuf, 4096, len + buf_align)) != 0) {
151 printf("write_file: error: posix_memalign failed with %d", r);
152 err = r;
153 goto out_close;
154 }
155
156 if (!direct)
157 ioctl(fd, CEPH_IOC_SYNCIO);
158
159 void *buf = (char *)rawbuf + buf_align;
160
161 generate_pattern(buf, len, offset);
162
163 r = pwrite(fd, buf, len, offset);
164 close(fd);
165
166 fd = open("foo", O_RDONLY);
167 if (fd < 0) {
168 err = errno;
169 printf("write_file: error: open() failed with: %d (%s)\n", err, strerror(err));
170 free(rawbuf);
171 goto out_unlink;
172 }
173 void *buf2 = malloc(len);
174 if (!buf2) {
175 err = -ENOMEM;
176 printf("write_file: error: malloc failed\n");
177 goto out_free;
178 }
179
180 memset(buf2, 0, len);
181 r = pread(fd, buf2, len, offset);
182 if (r == -1) {
183 err = errno;
184 printf("write_file: error: pread() failed with: %d (%s)\n", err, strerror(err));
185 goto out_free_buf;
186 }
187 r = verify_pattern(buf2, len, offset);
188
189 out_free_buf:
190 free(buf2);
191 out_free:
192 free(rawbuf);
193 out_close:
194 close(fd);
195 out_unlink:
196 unlink("foo");
197 if (err)
198 exit(err);
199 return r;
200 }
201
202 int write_direct(int buf_align, uint64_t offset, int len)
203 {
204 printf("write_direct buf_align %d offset %llu len %d\n", buf_align,
205 (unsigned long long)offset, len);
206 return write_file (buf_align, offset, len, 1);
207 }
208
209 int write_sync(int buf_align, uint64_t offset, int len)
210 {
211 printf("write_sync buf_align %d offset %llu len %d\n", buf_align,
212 (unsigned long long)offset, len);
213 return write_file (buf_align, offset, len, 0);
214 }
215
216 int main(int argc, char **argv)
217 {
218 uint64_t i, j, k;
219 int read = 1;
220 int write = 1;
221
222 if (argc >= 2 && strcmp(argv[1], "read") == 0)
223 write = 0;
224 if (argc >= 2 && strcmp(argv[1], "write") == 0)
225 read = 0;
226
227 if (read) {
228 write_pattern();
229
230 for (i = 0; i < 4096; i += 512)
231 for (j = 4*1024*1024 - 4096; j < 4*1024*1024 + 4096; j += 512)
232 for (k = 1024; k <= 16384; k *= 2) {
233 read_direct(i, j, k);
234 read_sync(i, j, k);
235 }
236
237 }
238 unlink("foo");
239 if (write) {
240 for (i = 0; i < 4096; i += 512)
241 for (j = 4*1024*1024 - 4096 + 512; j < 4*1024*1024 + 4096; j += 512)
242 for (k = 1024; k <= 16384; k *= 2) {
243 write_direct(i, j, k);
244 write_sync(i, j, k);
245 }
246 }
247
248
249 return 0;
250 }