ia64/xen-unstable

view tools/libaio/man/io.3 @ 10736:2937703f0ed0

Added blktap support. Includes kernel driver (enabled as CONFIG_XEN_BLKDEV_TAP=y) and userspace tools. The userspace deamon (blktapctrl) is enabled by default when xend is activated. For further information on using and configuring blktap see tools/blktap/README.
author jchesterfield@dhcp92.uk.xensource.com
date Thu Jul 13 10:13:26 2006 +0100 (2006-07-13)
parents
children
line source
1 .TH io 3 2002-09-12 "Linux 2.4" Linux IO"
2 .SH NAME
3 io \- Asynchronous IO
4 .SH SYNOPSYS
5 .nf
6 .B #include <errno.h>
7 .sp
8 .br
9 .B #include <libio.h>
10 .sp
11 .fi
12 .SH DESCRIPTION
13 The libaio library defines a new set of I/O operations which can
14 significantly reduce the time an application spends waiting at I/O. The
15 new functions allow a program to initiate one or more I/O operations and
16 then immediately resume normal work while the I/O operations are
17 executed in parallel.
19 These functions are part of the library with realtime functions named
20 .IR "libaio"
21 . They are not actually part of the
22 .IR "libc"
23 binary.
24 The implementation of these functions can be done using support in the
25 kernel.
27 All IO operations operate on files which were opened previously. There
28 might be arbitrarily many operations running for one file. The
29 asynchronous I/O operations are controlled using a data structure named
30 .IR "struct iocb"
31 It is defined in
32 .IR "libio.h"
33 as follows.
35 .nf
37 typedef struct io_context *io_context_t;
39 typedef enum io_iocb_cmd {
40 IO_CMD_PREAD = 0,
41 IO_CMD_PWRITE = 1,
43 IO_CMD_FSYNC = 2,
44 IO_CMD_FDSYNC = 3,
46 IO_CMD_POLL = 5,
47 IO_CMD_NOOP = 6,
48 } io_iocb_cmd_t;
50 struct io_iocb_common {
51 void *buf;
52 unsigned __pad1;
53 long nbytes;
54 unsigned __pad2;
55 long long offset;
56 long long __pad3, __pad4;
57 }; /* result code is the amount read or -'ve errno */
60 struct iocb {
61 void *data;
62 unsigned key;
63 short aio_lio_opcode;
64 short aio_reqprio;
65 int aio_fildes;
66 union {
67 struct io_iocb_common c;
68 struct io_iocb_vector v;
69 struct io_iocb_poll poll;
70 struct io_iocb_sockaddr saddr;
71 } u;
72 };
75 .fi
76 .TP
77 .IR "int aio_fildes"
78 This element specifies the file descriptor to be used for the
79 operation. It must be a legal descriptor, otherwise the operation will
80 fail.
82 The device on which the file is opened must allow the seek operation.
83 I.e., it is not possible to use any of the IO operations on devices
84 like terminals where an
85 .IR "lseek"
86 call would lead to an error.
87 .TP
88 .IR "long u.c.offset"
89 This element specifies the offset in the file at which the operation (input
90 or output) is performed. Since the operations are carried out in arbitrary
91 order and more than one operation for one file descriptor can be
92 started, one cannot expect a current read/write position of the file
93 descriptor.
94 .TP
95 .IR "void *buf"
96 This is a pointer to the buffer with the data to be written or the place
97 where the read data is stored.
98 .TP
99 .IR "long u.c.nbytes"
100 This element specifies the length of the buffer pointed to by
101 .IR "io_buf"
102 .
103 .TP
104 .IR "int aio_reqprio"
105 Is not currently used.
106 .TP
107 .B "IO_CMD_PREAD"
108 Start a read operation. Read from the file at position
109 .IR "u.c.offset"
110 and store the next
111 .IR "u.c.nbytes"
112 bytes in the
113 buffer pointed to by
114 .IR "buf"
115 .
116 .TP
117 .B "IO_CMD_PWRITE"
118 Start a write operation. Write
119 .IR "u.c.nbytes"
120 bytes starting at
121 .IR "buf"
122 into the file starting at position
123 .IR "u.c.offset"
124 .
125 .TP
126 .B "IO_CMD_NOP"
127 Do nothing for this control block. This value is useful sometimes when
128 an array of
129 .IR "struct iocb"
130 values contains holes, i.e., some of the
131 values must not be handled although the whole array is presented to the
132 .IR "io_submit"
133 function.
134 .TP
135 .B "IO_CMD_FSYNC"
136 .TP
137 .B "IO_CMD_POLL"
138 This is experimental.
139 .SH EXAMPLE
140 .nf
141 /*
142 * Simplistic version of copy command using async i/o
143 *
144 * From: Stephen Hemminger <shemminger@osdl.org>
145 * Copy file by using a async I/O state machine.
146 * 1. Start read request
147 * 2. When read completes turn it into a write request
148 * 3. When write completes decrement counter and free resources
149 *
150 *
151 * Usage: aiocp file(s) desination
152 */
154 #include <unistd.h>
155 #include <stdio.h>
156 #include <sys/types.h>
157 #include <sys/stat.h>
158 #include <sys/param.h>
159 #include <fcntl.h>
160 #include <errno.h>
162 #include <libaio.h>
164 #define AIO_BLKSIZE (64*1024)
165 #define AIO_MAXIO 32
167 static int busy = 0; // # of I/O's in flight
168 static int tocopy = 0; // # of blocks left to copy
169 static int dstfd = -1; // destination file descriptor
170 static const char *dstname = NULL;
171 static const char *srcname = NULL;
174 /* Fatal error handler */
175 static void io_error(const char *func, int rc)
176 {
177 if (rc == -ENOSYS)
178 fprintf(stderr, "AIO not in this kernel\n");
179 else if (rc < 0 && -rc < sys_nerr)
180 fprintf(stderr, "%s: %s\n", func, sys_errlist[-rc]);
181 else
182 fprintf(stderr, "%s: error %d\n", func, rc);
184 if (dstfd > 0)
185 close(dstfd);
186 if (dstname)
187 unlink(dstname);
188 exit(1);
189 }
191 /*
192 * Write complete callback.
193 * Adjust counts and free resources
194 */
195 static void wr_done(io_context_t ctx, struct iocb *iocb, long res, long res2)
196 {
197 if (res2 != 0) {
198 io_error("aio write", res2);
199 }
200 if (res != iocb->u.c.nbytes) {
201 fprintf(stderr, "write missed bytes expect %d got %d\n", iocb->u.c.nbytes, res2);
202 exit(1);
203 }
204 --tocopy;
205 --busy;
206 free(iocb->u.c.buf);
208 memset(iocb, 0xff, sizeof(iocb)); // paranoia
209 free(iocb);
210 write(2, "w", 1);
211 }
213 /*
214 * Read complete callback.
215 * Change read iocb into a write iocb and start it.
216 */
217 static void rd_done(io_context_t ctx, struct iocb *iocb, long res, long res2)
218 {
219 /* library needs accessors to look at iocb? */
220 int iosize = iocb->u.c.nbytes;
221 char *buf = iocb->u.c.buf;
222 off_t offset = iocb->u.c.offset;
224 if (res2 != 0)
225 io_error("aio read", res2);
226 if (res != iosize) {
227 fprintf(stderr, "read missing bytes expect %d got %d\n", iocb->u.c.nbytes, res);
228 exit(1);
229 }
232 /* turn read into write */
233 io_prep_pwrite(iocb, dstfd, buf, iosize, offset);
234 io_set_callback(iocb, wr_done);
235 if (1 != (res = io_submit(ctx, 1, &iocb)))
236 io_error("io_submit write", res);
237 write(2, "r", 1);
238 }
241 int main(int argc, char *const *argv)
242 {
243 int srcfd;
244 struct stat st;
245 off_t length = 0, offset = 0;
246 io_context_t myctx;
248 if (argc != 3 || argv[1][0] == '-') {
249 fprintf(stderr, "Usage: aiocp SOURCE DEST");
250 exit(1);
251 }
252 if ((srcfd = open(srcname = argv[1], O_RDONLY)) < 0) {
253 perror(srcname);
254 exit(1);
255 }
256 if (fstat(srcfd, &st) < 0) {
257 perror("fstat");
258 exit(1);
259 }
260 length = st.st_size;
262 if ((dstfd = open(dstname = argv[2], O_WRONLY | O_CREAT, 0666)) < 0) {
263 close(srcfd);
264 perror(dstname);
265 exit(1);
266 }
268 /* initialize state machine */
269 memset(&myctx, 0, sizeof(myctx));
270 io_queue_init(AIO_MAXIO, &myctx);
271 tocopy = howmany(length, AIO_BLKSIZE);
273 while (tocopy > 0) {
274 int i, rc;
275 /* Submit as many reads as once as possible upto AIO_MAXIO */
276 int n = MIN(MIN(AIO_MAXIO - busy, AIO_MAXIO / 2),
277 howmany(length - offset, AIO_BLKSIZE));
278 if (n > 0) {
279 struct iocb *ioq[n];
281 for (i = 0; i < n; i++) {
282 struct iocb *io = (struct iocb *) malloc(sizeof(struct iocb));
283 int iosize = MIN(length - offset, AIO_BLKSIZE);
284 char *buf = (char *) malloc(iosize);
286 if (NULL == buf || NULL == io) {
287 fprintf(stderr, "out of memory\n");
288 exit(1);
289 }
291 io_prep_pread(io, srcfd, buf, iosize, offset);
292 io_set_callback(io, rd_done);
293 ioq[i] = io;
294 offset += iosize;
295 }
297 rc = io_submit(myctx, n, ioq);
298 if (rc < 0)
299 io_error("io_submit", rc);
301 busy += n;
302 }
304 // Handle IO's that have completed
305 rc = io_queue_run(myctx);
306 if (rc < 0)
307 io_error("io_queue_run", rc);
309 // if we have maximum number of i/o's in flight
310 // then wait for one to complete
311 if (busy == AIO_MAXIO) {
312 rc = io_queue_wait(myctx, NULL);
313 if (rc < 0)
314 io_error("io_queue_wait", rc);
315 }
317 }
319 close(srcfd);
320 close(dstfd);
321 exit(0);
322 }
324 /*
325 * Results look like:
326 * [alanm@toolbox ~/MOT3]$ ../taio kernel-source-2.4.8-0.4g.ppc.rpm abc
327 * rrrrrrrrrrrrrrrwwwrwrrwwrrwrwwrrwrwrwwrrwrwrrrrwwrwwwrrwrrrwwwwwwwwwwwwwwwww
328 * rrrrrrrrrrrrrrwwwrrwrwrwrwrrwwwwwwwwwwwwwwrrrrrrrrrrrrrrrrrrwwwwrwrwwrwrwrwr
329 * wrrrrrrrwwwwwwwwwwwwwrrrwrrrwrrwrwwwwwwwwwwrrrrwwrwrrrrrrrrrrrwwwwwwwwwwwrww
330 * wwwrrrrrrrrwwrrrwwrwrwrwwwrrrrrrrwwwrrwwwrrwrwwwwwwwwrrrrrrrwwwrrrrrrrwwwwww
331 * wwwwwwwrwrrrrrrrrwrrwrrwrrwrwrrrwrrrwrrrwrwwwwwwwwwwwwwwwwwwrrrwwwrrrrrrrrrr
332 * rrwrrrrrrwrrwwwwwwwwwwwwwwwwrwwwrrwrwwrrrrrrrrrrrrrrrrrrrwwwwwwwwwwwwwwwwwww
333 * rrrrrwrrwrwrwrrwrrrwwwwwwwwrrrrwrrrwrwwrwrrrwrrwrrrrwwwwwwwrwrwwwwrwwrrrwrrr
334 * rrrwwwwwwwrrrrwwrrrrrrrrrrrrwrwrrrrwwwwwwwwwwwwwwrwrrrrwwwwrwrrrrwrwwwrrrwww
335 * rwwrrrrrrrwrrrrrrrrrrrrwwwwrrrwwwrwrrwwwwwwwwwwwwwwwwwwwwwrrrrrrrwwwwwwwrw
336 */
337 .fi
338 .SH "SEE ALSO"
339 .BR io_cancel(3),
340 .BR io_fsync(3),
341 .BR io_getevents(3),
342 .BR io_prep_fsync(3),
343 .BR io_prep_pread(3),
344 .BR io_prep_pwrite(3),
345 .BR io_queue_init(3),
346 .BR io_queue_release(3),
347 .BR io_queue_run(3),
348 .BR io_queue_wait(3),
349 .BR io_set_callback(3),
350 .BR io_submit(3),
351 .BR errno(3)