Home | History | Annotate | Download | only in ltp-aiodio
      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