1 /* 2 * Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved. 3 * Copyright (c) International Business Machines Corp., 2002 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of 8 * the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it would 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, see <http://www.gnu.org/licenses/>. 17 * 18 * DESCRIPTION 19 * Copy the contents of the input file to output file using direct read 20 * and direct write. The input file size is numblks*bufsize. 21 * The read and write calls use bufsize to perform IO. Input and output 22 * files can be specified through commandline and is useful for running 23 * test with raw devices as files. 24 * 25 * USAGE 26 * diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile] 27 * 28 * History 29 * 04/22/2002 Narasimha Sharoff nsharoff (at) us.ibm.com 30 */ 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <unistd.h> 35 #include <signal.h> 36 #include <string.h> 37 #include <fcntl.h> 38 #include <errno.h> 39 40 #include "diotest_routines.h" 41 42 #include "test.h" 43 #include "safe_macros.h" 44 45 char *TCID = "diotest01"; /* Test program identifier. */ 46 int TST_TOTAL = 1; /* Total number of test conditions */ 47 48 #ifdef O_DIRECT 49 50 #define BUFSIZE 8192 51 #define NBLKS 20 52 #define LEN 30 53 #define TRUE 1 54 55 static char infile[LEN]; /* Input file. Default "infile" */ 56 static char outfile[LEN]; /* Output file. Default "outfile" */ 57 static int fd1, fd2; 58 59 /* 60 * prg_usage: display the program usage. 61 */ 62 void prg_usage(void) 63 { 64 fprintf(stderr, 65 "Usage: diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile]\n"); 66 tst_brkm(TBROK, NULL, "usage"); 67 } 68 69 void cleanup(void) 70 { 71 if (fd1 > 0) 72 close(fd1); 73 if (fd2 > 0) 74 close(fd2); 75 76 tst_rmdir(); 77 } 78 79 int main(int argc, char *argv[]) 80 { 81 int bufsize = BUFSIZE; /* Buffer size. Default 8k */ 82 int numblks = NBLKS; /* Number of blocks. Default 20 */ 83 int i, n, offset; 84 char *buf; 85 86 /* Options */ 87 strcpy(infile, "infile"); /* Default input file */ 88 strcpy(outfile, "outfile"); /* Default outfile file */ 89 while ((i = getopt(argc, argv, "b:n:i:o:")) != -1) { 90 switch (i) { 91 case 'b': 92 if ((bufsize = atoi(optarg)) <= 0) { 93 fprintf(stderr, "bufsize must be > 0\n"); 94 prg_usage(); 95 } 96 if (bufsize % 4096 != 0) { 97 fprintf(stderr, 98 "bufsize must be multiple of 4k\n"); 99 prg_usage(); 100 } 101 break; 102 case 'n': 103 if ((numblks = atoi(optarg)) <= 0) { 104 fprintf(stderr, "numblks must be > 0\n"); 105 prg_usage(); 106 } 107 break; 108 case 'i': 109 strcpy(infile, optarg); 110 break; 111 case 'o': 112 strcpy(outfile, optarg); 113 break; 114 default: 115 prg_usage(); 116 } 117 } 118 119 tst_tmpdir(); 120 121 /* Test for filesystem support of O_DIRECT */ 122 int fd = open(infile, O_DIRECT | O_RDWR | O_CREAT, 0666); 123 124 if (fd < 0) 125 tst_brkm(TCONF, cleanup, "O_DIRECT not supported by FS"); 126 SAFE_CLOSE(cleanup, fd); 127 128 /* Open files */ 129 fd1 = SAFE_OPEN(cleanup, infile, O_DIRECT | O_RDWR | O_CREAT, 0666); 130 fd2 = SAFE_OPEN(cleanup, outfile, O_DIRECT | O_RDWR | O_CREAT, 0666); 131 132 /* Allocate for buf, Create input file */ 133 buf = valloc(bufsize); 134 135 if (!buf) 136 tst_brkm(TFAIL | TERRNO, cleanup, "valloc() failed"); 137 138 for (i = 0; i < numblks; i++) { 139 fillbuf(buf, bufsize, (char)(i % 256)); 140 SAFE_WRITE(cleanup, 1, fd1, buf, bufsize); 141 } 142 143 /* Copy infile to outfile using direct read and direct write */ 144 offset = 0; 145 SAFE_LSEEK(cleanup, fd1, offset, SEEK_SET); 146 147 while ((n = read(fd1, buf, bufsize)) > 0) { 148 SAFE_LSEEK(cleanup, fd2, offset, SEEK_SET); 149 150 SAFE_WRITE(cleanup, 1, fd2, buf, n); 151 152 offset += n; 153 SAFE_LSEEK(cleanup, fd1, offset, SEEK_SET); 154 } 155 156 /* Verify */ 157 if (filecmp(infile, outfile) != 0) { 158 tst_brkm(TFAIL, cleanup, "file compare failed for %s and %s", 159 infile, outfile); 160 } 161 162 tst_resm(TPASS, "Test passed"); 163 164 cleanup(); 165 tst_exit(); 166 } 167 168 #else /* O_DIRECT */ 169 170 int main() 171 { 172 tst_brkm(TCONF, NULL, "O_DIRECT is not defined."); 173 } 174 #endif /* O_DIRECT */ 175