Imported Upstream version 20091031
[ltp-debian.git] / testcases / kernel / io / aio / aio02 / aio_tio.c
blobe0bb3961754fc8f860c366304101e69f59caa7ca
1 /*************************************************************************************
3 * Copyright (c) International Business Machines Corp., 2003
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the 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 to the Free Software
17 * Foundation,
19 * FILE : aio_tio
20 * USAGE : runfstest case/aio_tio
22 * DESCRIPTION : This program will test Asynchronous I/O for 2.5 Kernel infrastructure
23 * REQUIREMENTS:
24 * 1) libaio-0.3.92 or up for 2.5 kernal
25 * 2) glibc 2.1.91 or up
26 * HISTORY :
27 * 11/03/2003 Kai Zhao (ltcd3@cn.ibm.com)
29 * CODE COVERAGE:
30 * 68.3% - fs/aio.c
32 ************************************************************************************/
34 #include "config.h"
35 #include "common.h"
36 #include "test.h"
37 #include <string.h>
38 #include <errno.h>
40 #if HAVE_LIBAIO_H
42 #define AIO_MAXIO 32
43 #define AIO_BLKSIZE (64*1024)
45 static int alignment = 512;
46 static int wait_count = 0;
49 * write work done
51 static void work_done(io_context_t ctx, struct iocb *iocb, long res, long res2)
54 if (res2 != 0) {
55 io_error("aio write", res2);
58 if (res != iocb->u.c.nbytes) {
59 fprintf(stderr, "write missed bytes expect %lu got %ld\n",
60 iocb->u.c.nbytes, res2);
61 exit(1);
63 wait_count --;
67 * io_wait_run() - wait for an io_event and then call the callback.
69 int io_wait_run(io_context_t ctx, struct timespec *to)
71 struct io_event events[AIO_MAXIO];
72 struct io_event *ep;
73 int ret, n;
76 * get up to aio_maxio events at a time.
78 ret = n = io_getevents(ctx, 1, AIO_MAXIO, events, to);
81 * Call the callback functions for each event.
83 for (ep = events ; n-- > 0 ; ep++) {
84 io_callback_t cb = (io_callback_t)ep->data ; struct iocb *iocb = ep->obj ; cb(ctx, iocb, ep->res, ep->res2);
86 return ret;
90 int io_tio(char *pathname, int flag, int n, int operation)
92 int res, fd = 0, i = 0;
93 void * bufptr = NULL;
94 off_t offset = 0;
95 struct timespec timeout;
97 io_context_t myctx;
98 struct iocb iocb_array[AIO_MAXIO];
99 struct iocb *iocbps[AIO_MAXIO];
101 fd = open (pathname, flag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
102 if (fd <= 0) {
103 printf("open for %s failed: %s\n", pathname, strerror(errno));
104 return -1;
107 res = io_queue_init(n, &myctx);
108 //printf (" res = %d \n", res);
110 for (i = 0 ; i < AIO_MAXIO ; i ++) {
112 switch (operation) {
113 case IO_CMD_FSYNC :
114 case IO_CMD_FDSYNC :
115 case IO_CMD_PWRITE :
116 if (posix_memalign (&bufptr, alignment, AIO_BLKSIZE)) {
117 perror (" posix_memalign failed ");
118 return -1;
120 memset (bufptr, 0, AIO_BLKSIZE);
122 io_prep_pwrite (&iocb_array[i], fd, bufptr ,
123 AIO_BLKSIZE, offset);
124 io_set_callback(&iocb_array[i], work_done);
125 iocbps[i] = &iocb_array[i];
126 offset += AIO_BLKSIZE;
128 break;
129 case IO_CMD_PREAD :
130 if (posix_memalign (&bufptr, alignment, AIO_BLKSIZE)) {
131 perror (" posix_memalign failed ");
132 return -1;
134 memset (bufptr, 0, AIO_BLKSIZE);
136 io_prep_pread (&iocb_array[i], fd, bufptr ,
137 AIO_BLKSIZE, offset);
138 io_set_callback(&iocb_array[i], work_done);
139 iocbps[i] = &iocb_array[i];
140 offset += AIO_BLKSIZE;
141 break;
142 case IO_CMD_POLL :
143 case IO_CMD_NOOP :
144 break;
145 default:
146 tst_resm (TFAIL,
147 "Command failed; opcode returned: %d\n",
148 operation);
149 return -1;
150 break;
154 do {
155 res = io_submit(myctx, AIO_MAXIO, iocbps);
156 } while (res == -EAGAIN);
157 if (res < 0) {
158 io_error("io_submit tio", res);
162 * We have submitted all the i/o requests. Wait for at least one to complete
163 * and call the callbacks.
165 wait_count = AIO_MAXIO;
167 timeout.tv_sec = 30;
168 timeout.tv_nsec = 0;
170 switch (operation) {
171 case IO_CMD_PREAD :
172 case IO_CMD_PWRITE :
174 while (wait_count) {
175 res = io_wait_run(myctx, &timeout);
176 if (res < 0)
177 io_error("io_wait_run", res);
180 break;
181 case IO_CMD_FSYNC :
182 for (i = 0 ; i < AIO_MAXIO ; i ++) {
183 res = io_fsync(myctx, iocbps[i], work_done, fd);
184 if (res < 0) {
185 io_error("io_fsync write", res);
188 break;
189 case IO_CMD_FDSYNC :
190 for (i = 0 ; i < AIO_MAXIO ; i ++) {
191 res = io_fdsync(myctx, iocbps[i], work_done, fd);
192 if (res < 0) {
193 io_error("io_fsync write", res);
196 break;
200 close (fd);
202 for (i = 0 ; i < AIO_MAXIO ; i ++) {
203 if (iocb_array[i].u.c.buf != NULL) {
204 free (iocb_array[i].u.c.buf);
208 io_queue_release (myctx);
210 return 0;
213 int test_main(void)
215 int status = 0 ;
217 tst_resm(TINFO, "Running test 1\n");
218 status = io_tio("testdir/file1",
219 O_TRUNC | O_DIRECT | O_WRONLY | O_CREAT | O_LARGEFILE,
220 AIO_MAXIO, IO_CMD_PWRITE);
221 if (status) {
222 return status;
225 tst_resm(TINFO, "Running test 2\n");
226 status = io_tio("testdir/file1", O_RDONLY | O_DIRECT | O_LARGEFILE,
227 AIO_MAXIO, IO_CMD_PREAD);
228 if (status) {
229 return status;
232 tst_resm(TINFO, "Running test 3\n");
233 status = io_tio("testdir/file1", O_TRUNC | O_RDWR,
234 AIO_MAXIO, IO_CMD_PWRITE);
235 if (status) {
236 return status;
239 tst_resm(TINFO, "Running test 4\n");
240 status = io_tio("testdir/file1", O_RDWR,
241 AIO_MAXIO, IO_CMD_PREAD);
242 if (status) {
243 return status;
246 tst_resm(TINFO, "Running test 5\n");
247 status = io_tio("testdir/file1", O_TRUNC | O_WRONLY,
248 AIO_MAXIO, IO_CMD_PWRITE);
249 if (status) {
250 return status;
253 tst_resm(TINFO, "Running test 6 \n");
254 status = io_tio("testdir/file1", O_RDONLY,
255 AIO_MAXIO, IO_CMD_PREAD);
256 if (status) {
257 return status;
260 tst_resm(TINFO, "Running test 7 \n");
261 status = io_tio("testdir/file2",
262 O_TRUNC | O_DIRECT | O_WRONLY | O_CREAT | O_LARGEFILE,
263 AIO_MAXIO, IO_CMD_FSYNC);
264 if (status) {
265 return status;
268 tst_resm(TINFO, "Running test 8 \n");
269 status = io_tio("testdir/file2",
270 O_TRUNC | O_DIRECT | O_WRONLY | O_CREAT | O_LARGEFILE,
271 AIO_MAXIO, IO_CMD_FDSYNC);
272 if (status) {
273 return status;
276 return status;
279 #endif