aio-dio: fix error msg in aio-dio-subblock-eof-read.c
[xfstests-dev.git] / src / aio-dio-regress / aio-dio-subblock-eof-read.c
1 /*
2  *   aio-dio-subblock-eof-read - test AIO read of last block of DIO file
3  *   Copyright (C) 2005 Jeff Moyer
4  *
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.
9  *
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 the
13  *   GNU General Public License for more details.
14  *
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, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19  
20 /*
21  *  Code taken from an example posted to linux-aio at kvack.org
22  *  http://marc.info/?l=linux-aio&m=112263621431161&w=2
23  *  Original Author: Drangon Zhou
24  *  Munged & rewritten by Jeff Moyer.
25  *
26  *  Description:  This source code implements a test to ensure that an AIO
27  *  read of the last block in a file opened with O_DIRECT returns the proper
28  *  amount of data.  In the past, there was a bug that resulted in a return
29  *  value of the requested block size, when in fact there was only a fraction
30  *  of that data available.  Thus, if the last data block contained 300 bytes
31  *  worth of data, and the user issued a 4k read, we want to ensure that
32  *  the return value is 300, not 4k.
33  */
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <libaio.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <errno.h>
40
41 /* Create a file of a size that is not a multiple of block size */
42 #define FILE_SIZE       300
43
44 #define fail(fmt , args...)     \
45 do {                            \
46         printf(fmt , ##args);   \
47         exit(1);                \
48 } while (0)
49
50 static unsigned char buffer[4096] __attribute((aligned (4096)));
51
52 int
53 main(int argc, char **argv)
54 {
55         int ret;
56         int fd;
57         const char *filename;
58         struct iocb myiocb;
59         struct iocb *cb = &myiocb;
60         io_context_t ioctx;
61         struct io_event ie;
62     
63         if (argc != 2)
64                 fail("only arg should be file name");
65
66         filename = argv[1];
67         fd = open(filename, O_CREAT|O_RDWR|O_DIRECT, 0600);
68         if (fd < 0)
69                 fail("open returned error %d\n", errno);
70
71         ret = ftruncate(fd, FILE_SIZE);
72         if (ret < 0)
73                 fail("truncate returned error %d\n", errno);
74
75         /* <1> use normal disk read, this should be ok */
76         ret = read(fd, buffer, 4096);
77         if (ret != FILE_SIZE)
78                 fail("buffered read returned %d, should be 300\n", ret);
79
80         /* <2> use AIO disk read, it sees error. */
81         memset(&myiocb, 0, sizeof(myiocb));
82         cb->data = 0;
83         cb->key = 0;
84         cb->aio_lio_opcode = IO_CMD_PREAD;
85         cb->aio_reqprio = 0; 
86         cb->aio_fildes = fd; 
87         cb->u.c.buf = buffer;
88         cb->u.c.nbytes = 4096;
89         cb->u.c.offset = 0;
90     
91         ret = io_queue_init(1, &ioctx);
92         if (ret != 0)
93                 fail("io_queue_init returned error %d\n", ret);
94
95         ret = io_submit(ioctx, 1, &cb);
96         if (ret != 1)
97                 fail("io_submit returned error %d\n", ret);
98
99         ret = io_getevents(ioctx, 1, 1, &ie, NULL);
100         if (ret != 1)
101                 fail("io_getevents returned %d\n", ret);
102
103         /*
104          *  If all goes well, we should see 300 bytes read.  If things
105          *  are broken, we may very well see a result of 4k.
106          */
107         if (ie.res != FILE_SIZE)
108                 fail("AIO read of last block in file returned %ld bytes, "
109                      "expected %d\n", ie.res, FILE_SIZE);
110
111         printf("AIO read of last block in file succeeded.\n");
112         return 0;
113 }