• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 */
prg_usage(void)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 
cleanup(void)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 
main(int argc,char * argv[])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, SAFE_WRITE_ALL, 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, SAFE_WRITE_ALL, 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 
main()170 int main()
171 {
172 	tst_brkm(TCONF, NULL, "O_DIRECT is not defined.");
173 }
174 #endif /* O_DIRECT */
175