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