2 * Copyright (c) 2013 Alibaba Group.
3 * Copyright (c) 2017 Red Hat Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it would be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 * This is a normal case that we do some append dio writes and meanwhile
22 * we do some dio reads. Currently in vfs we don't ensure that i_size
23 * is updated properly. Hence the reader will read some data with '0'.
24 * But we expect that the reader should read nothing or data with 'a'.
32 #include <sys/types.h>
50 static void usage(const char *prog)
52 fprintf(stderr, "usage: %s [-a] <file>\n", prog);
53 fprintf(stderr, "\t-a\tuse aio-dio\n");
57 static void *reader(void *arg)
59 struct io_data *data = (struct io_data *)arg;
62 memset(data->buf, 'b', data->blksize);
65 ret = pread(data->fd, data->buf, data->blksize, data->offset);
73 #define fail(fmt , args...) do { \
74 fprintf(stderr, fmt , ##args); \
78 static void *writer(struct io_data *data)
86 struct io_context *ctx = NULL;
87 struct io_event evs[1];
89 struct iocb *iocbs[] = { &iocb };
91 ret = io_setup(1, &ctx);
93 fail("error %s during io_setup\n", strerror(ret));
94 io_prep_pwrite(&iocb, data->fd, data->buf, data->blksize, data->offset);
95 ret = io_submit(ctx, 1, iocbs);
97 fail("error %s during io_submit\n", strerror(ret));
98 ret = io_getevents(ctx, 1, 1, evs, NULL);
100 fail("error %s during io_getevents\n", strerror(ret));
101 if ((signed)evs[0].res < 0)
102 fail("error %s during write\n", strerror(-evs[0].res));
103 if ((signed)evs[0].res2 < 0)
104 fail("secondary error %s during write\n", strerror(-evs[0].res2));
106 ret = pwrite(data->fd, data->buf, data->blksize, data->offset);
108 fail("write file failed: %s", strerror(errno));
114 int main(int argc, char *argv[])
117 struct io_data wdata;
118 struct io_data rdata;
119 size_t max_blocks = 128; /* 128 */
120 size_t blksize = 1 * 1024 * 1024; /* 1M */
121 char *rbuf = NULL, *wbuf = NULL;
122 int rfd = 0, wfd = 0;
131 prog = basename(argv[0]);
133 while ((c = getopt(argc, argv, "a:d")) != -1) {
136 io_align = strtol(optarg, NULL, 0);
145 if (optind != argc - 1)
147 testfile = argv[optind];
149 wfd = open(testfile, O_CREAT|O_DIRECT|O_WRONLY|O_TRUNC, 0644);
151 perror("open for write");
155 rfd = open(testfile, O_DIRECT|O_RDONLY, 0644);
157 perror("open for read");
162 ret = posix_memalign((void **)&wbuf, io_align, blksize);
164 fail("failed to alloc memory: %s\n", strerror(ret));
169 ret = posix_memalign((void **)&rbuf, io_align, blksize);
171 fail("failed to alloc memory: %s\n", strerror(ret));
176 memset(wbuf, 'a', blksize);
178 wdata.blksize = blksize;
180 wdata.use_aio = use_aio;
182 rdata.blksize = blksize;
185 for (i = 0; i < max_blocks; i++) {
186 wdata.offset = rdata.offset = i * blksize;
188 /* reset reader_ready, it will be set in reader thread */
190 ret = pthread_create(&tid, NULL, reader, &rdata);
192 fail("create reader thread failed: %s\n", strerror(ret));
199 ret = pthread_join(tid, NULL);
201 fail("pthread join reader failed: %s\n", strerror(ret));
206 for (j = 0; j < blksize; j++) {
207 if (rdata.buf[j] != 'a') {
208 fail("encounter an error: "
209 "block %d offset %d, content %x\n",