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 (at) 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 (at) 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 <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 53 void assert(const char *what, int assertion) 54 { 55 if (assertion) 56 return; 57 perror(what); 58 exit(1); 59 } 60 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 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 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