1 /*
2 * Copyright (C) 2003,2004 Red Hat, Inc. All rights reserved.
3 *
4 * The contents of this file may be used under the terms of the GNU
5 * General Public License version 2 (the "GPL")
6 *
7 * Author: Stephen C. Tweedie <sct@redhat.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * Module: .c
23 */
24
25 /*
26 * Change History:
27 *
28 * 2/2004 Marty Ridgeway (mridge@us.ibm.com) Changes to adapt to LTP
29 *
30 */
31
32 #define _XOPEN_SOURCE 600
33 #define _GNU_SOURCE
34 #define MAX_ITERATIONS 250
35
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <sys/fcntl.h>
42 #include <sys/mman.h>
43 #include <sys/wait.h>
44
45 #define BIGSIZE 128*1024*1024
46 #define READSIZE 32*1024*1024
47 #define WRITESIZE 32*1024*1024
48
49 int pagesize;
50 char *iobuf;
51 int pass = 0;
52
assert(const char * what,int assertion)53 void assert(const char *what, int assertion)
54 {
55 if (assertion)
56 return;
57 perror(what);
58 exit(1);
59 }
60
do_buffered_writes(int fd,int pattern)61 void do_buffered_writes(int fd, int pattern)
62 {
63 int rc;
64 int offset;
65
66 memset(iobuf, pattern, WRITESIZE);
67 for (offset = 0; offset + WRITESIZE <= BIGSIZE; offset += WRITESIZE) {
68 rc = pwrite(fd, iobuf, WRITESIZE, offset);
69 assert("pwrite", rc >= 0);
70 if (rc != WRITESIZE) {
71 fprintf(stderr, "Pass %d: short write (%d out of %d)\n",
72 pass, rc, WRITESIZE);
73 exit(1);
74 }
75 fsync(fd);
76 }
77 }
78
do_direct_reads(char * filename)79 int do_direct_reads(char *filename)
80 {
81 int fd;
82 int offset;
83 int rc, i;
84 int *p;
85
86 fd = open(filename, O_DIRECT | O_RDONLY, 0);
87 assert("open", fd >= 0);
88
89 for (offset = 0; offset + READSIZE <= BIGSIZE; offset += READSIZE) {
90 rc = pread(fd, iobuf, READSIZE, offset);
91 assert("pread", rc >= 0);
92 if (rc != READSIZE) {
93 fprintf(stderr, "Pass: %d short read (%d out of %d)\n",
94 pass, rc, READSIZE);
95 exit(1);
96 }
97 for (i = 0, p = (int *)iobuf; i < READSIZE; i += 4) {
98 if (*p) {
99 fprintf(stderr,
100 "Pass: %d Found data (%08x) at offset %d+%d\n",
101 pass, *p, offset, i);
102 close(fd);
103 return 1;
104 }
105 p++;
106 }
107 }
108 close(fd);
109 return 0;
110 }
111
main(int argc,char * argv[])112 int main(int argc, char *argv[])
113 {
114 char *filename;
115 int fd;
116 int pid;
117 int err;
118 int bufsize;
119
120 if (argc != 2) {
121 fprintf(stderr, "Needs a filename as an argument.\n");
122 exit(1);
123 }
124
125 filename = argv[1];
126
127 pagesize = getpagesize();
128 bufsize = READSIZE;
129 if (WRITESIZE > READSIZE)
130 bufsize = WRITESIZE;
131 err = posix_memalign((void **)&iobuf, pagesize, bufsize);
132 if (err) {
133 fprintf(stderr, "Error allocating %d aligned bytes.\n",
134 bufsize);
135 exit(1);
136 }
137
138 fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0666);
139 assert("open", fd >= 0);
140
141 do {
142
143 assert("ftruncate", ftruncate(fd, BIGSIZE) == 0);
144 fsync(fd);
145
146 pid = fork();
147 assert("fork", pid >= 0);
148
149 if (!pid) {
150 do_buffered_writes(fd, 0);
151 exit(0);
152 }
153
154 err = do_direct_reads(filename);
155
156 wait4(pid, NULL, WNOHANG, 0);
157
158 if (err)
159 break;
160
161 /* Fill the file with a known pattern so that the blocks
162 * on disk can be detected if they become exposed. */
163 do_buffered_writes(fd, 1);
164 fsync(fd);
165
166 assert("ftruncate", ftruncate(fd, 0) == 0);
167 fsync(fd);
168 } while (pass++ < MAX_ITERATIONS);
169
170 if (!err) {
171 fprintf(stdout, "ltp-diorh: Completed %d iterations OK \n",
172 pass);
173 }
174
175 return err;
176 }
177