1f08c3bdfSopenharmony_ci/******************************************************************************
2f08c3bdfSopenharmony_ci *				 fallocate03.c
3f08c3bdfSopenharmony_ci *	Mon Dec 24 2007
4f08c3bdfSopenharmony_ci *	Copyright (c) International Business Machines  Corp., 2007
5f08c3bdfSopenharmony_ci *	Emali : sharyathi@in.ibm.com
6f08c3bdfSopenharmony_ci ******************************************************************************/
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ci/***************************************************************************
9f08c3bdfSopenharmony_ci * This program is free software;  you can redistribute it and/or modify
10f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by
11f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or
12f08c3bdfSopenharmony_ci * (at your option) any later version.
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful,
15f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
16f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17f08c3bdfSopenharmony_ci * GNU Library General Public License for more details.
18f08c3bdfSopenharmony_ci *
19f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License
20f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software
21f08c3bdfSopenharmony_ci * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22f08c3bdfSopenharmony_ci***************************************************************************/
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_ci/*****************************************************************************
25f08c3bdfSopenharmony_ci *
26f08c3bdfSopenharmony_ci *	OS Test - International Business Machines Corp. 2007.
27f08c3bdfSopenharmony_ci *
28f08c3bdfSopenharmony_ci *	TEST IDENTIFIER	: fallocate03
29f08c3bdfSopenharmony_ci *
30f08c3bdfSopenharmony_ci *	EXECUTED BY		: anyone
31f08c3bdfSopenharmony_ci *
32f08c3bdfSopenharmony_ci *	TEST TITLE		: fallocate
33f08c3bdfSopenharmony_ci *
34f08c3bdfSopenharmony_ci *	TEST CASE TOTAL	: 8
35f08c3bdfSopenharmony_ci *
36f08c3bdfSopenharmony_ci *	CPU ARCHITECTURES	: PPC,X86, X86_64
37f08c3bdfSopenharmony_ci *
38f08c3bdfSopenharmony_ci *	AUTHOR			: Sharyathi Nagesh
39f08c3bdfSopenharmony_ci *
40f08c3bdfSopenharmony_ci *	CO-PILOT			:
41f08c3bdfSopenharmony_ci *
42f08c3bdfSopenharmony_ci *	DATE STARTED		: 24/12/2007
43f08c3bdfSopenharmony_ci *
44f08c3bdfSopenharmony_ci *	TEST CASES
45f08c3bdfSopenharmony_ci *	(Working of fallocate on a sparse file)
46f08c3bdfSopenharmony_ci *
47f08c3bdfSopenharmony_ci *
48f08c3bdfSopenharmony_ci *	INPUT SPECIFICATIONS
49f08c3bdfSopenharmony_ci *		No input needs to be specified
50f08c3bdfSopenharmony_ci *		  fallocate() in-puts are specified through test_data
51f08c3bdfSopenharmony_ci *
52f08c3bdfSopenharmony_ci *	OUTPUT SPECIFICATIONS
53f08c3bdfSopenharmony_ci *		Output describing whether test cases passed or failed.
54f08c3bdfSopenharmony_ci *
55f08c3bdfSopenharmony_ci *	ENVIRONMENTAL NEEDS
56f08c3bdfSopenharmony_ci *		Test Needs to be executed on file system supporting ext4
57f08c3bdfSopenharmony_ci *   LTP {TMP} Needs to be set to such a folder
58f08c3bdfSopenharmony_ci *
59f08c3bdfSopenharmony_ci *	SPECIAL PROCEDURAL REQUIREMENTS
60f08c3bdfSopenharmony_ci *		None
61f08c3bdfSopenharmony_ci *
62f08c3bdfSopenharmony_ci *	DETAILED DESCRIPTION
63f08c3bdfSopenharmony_ci *		This is a test case for fallocate() system call.
64f08c3bdfSopenharmony_ci *		This test suite tests working of fallocate on sparse file
65f08c3bdfSopenharmony_ci *		fallocate is tested for different offsets
66f08c3bdfSopenharmony_ci *
67f08c3bdfSopenharmony_ci *		Total 8 Test Cases :-
68f08c3bdfSopenharmony_ci *			Different offsets with in a sparse file is tested
69f08c3bdfSopenharmony_ci *
70f08c3bdfSopenharmony_ci *	Setup:
71f08c3bdfSopenharmony_ci *		Setup file on which fallocate is to be called
72f08c3bdfSopenharmony_ci *		Set up a file with hole, created through lseek
73f08c3bdfSopenharmony_ci *
74f08c3bdfSopenharmony_ci *	Test:
75f08c3bdfSopenharmony_ci *		Loop if the proper options are given
76f08c3bdfSopenharmony_ci *		Execute system call
77f08c3bdfSopenharmony_ci *		Check return code, if system call failed
78f08c3bdfSopenharmony_ci *		TEST fails, PASS the test otherwise
79f08c3bdfSopenharmony_ci *
80f08c3bdfSopenharmony_ci *	Cleanup:
81f08c3bdfSopenharmony_ci *		Cleanup the temporary folder
82f08c3bdfSopenharmony_ci *
83f08c3bdfSopenharmony_ci*************************************************************************/
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ci#define _GNU_SOURCE
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_ci#include <stdio.h>
88f08c3bdfSopenharmony_ci#include <stdlib.h>
89f08c3bdfSopenharmony_ci#include <endian.h>
90f08c3bdfSopenharmony_ci#include <errno.h>
91f08c3bdfSopenharmony_ci#include <sys/stat.h>
92f08c3bdfSopenharmony_ci#include <sys/types.h>		//Can be done with out
93f08c3bdfSopenharmony_ci#include <fcntl.h>
94f08c3bdfSopenharmony_ci#include <unistd.h>
95f08c3bdfSopenharmony_ci#include <inttypes.h>
96f08c3bdfSopenharmony_ci#include <sys/utsname.h>
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_ci#include "test.h"
99f08c3bdfSopenharmony_ci#include "safe_macros.h"
100f08c3bdfSopenharmony_ci#include "lapi/fallocate.h"
101f08c3bdfSopenharmony_ci
102f08c3bdfSopenharmony_ci#define BLOCKS_WRITTEN 12
103f08c3bdfSopenharmony_ci#define HOLE_SIZE_IN_BLOCKS 12
104f08c3bdfSopenharmony_ci#define DEFAULT_MODE 0
105f08c3bdfSopenharmony_ci#define TRUE 0
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_civoid get_blocksize(int);
108f08c3bdfSopenharmony_civoid populate_file();
109f08c3bdfSopenharmony_civoid file_seek(off_t);
110f08c3bdfSopenharmony_ci
111f08c3bdfSopenharmony_cichar *TCID = "fallocate03";
112f08c3bdfSopenharmony_cichar fname[255];
113f08c3bdfSopenharmony_ciint fd;
114f08c3bdfSopenharmony_cistruct test_data_t {
115f08c3bdfSopenharmony_ci	int mode;
116f08c3bdfSopenharmony_ci	loff_t offset;
117f08c3bdfSopenharmony_ci	loff_t len;
118f08c3bdfSopenharmony_ci	int error;
119f08c3bdfSopenharmony_ci} test_data[] = {
120f08c3bdfSopenharmony_ci	{
121f08c3bdfSopenharmony_ci	DEFAULT_MODE, 2, 1, TRUE}, {
122f08c3bdfSopenharmony_ci	DEFAULT_MODE, BLOCKS_WRITTEN, 1, TRUE}, {
123f08c3bdfSopenharmony_ci	DEFAULT_MODE, BLOCKS_WRITTEN + HOLE_SIZE_IN_BLOCKS / 2 - 1, 1, TRUE},
124f08c3bdfSopenharmony_ci	{
125f08c3bdfSopenharmony_ci	DEFAULT_MODE, BLOCKS_WRITTEN + HOLE_SIZE_IN_BLOCKS + 1, 1, TRUE}, {
126f08c3bdfSopenharmony_ci	FALLOC_FL_KEEP_SIZE, 2, 1, TRUE}, {
127f08c3bdfSopenharmony_ci	FALLOC_FL_KEEP_SIZE, BLOCKS_WRITTEN, 1, TRUE}, {
128f08c3bdfSopenharmony_ci	FALLOC_FL_KEEP_SIZE,
129f08c3bdfSopenharmony_ci		    BLOCKS_WRITTEN + HOLE_SIZE_IN_BLOCKS / 2 + 1, 1, TRUE}, {
130f08c3bdfSopenharmony_ci	FALLOC_FL_KEEP_SIZE, BLOCKS_WRITTEN + HOLE_SIZE_IN_BLOCKS + 2,
131f08c3bdfSopenharmony_ci		    1, TRUE}
132f08c3bdfSopenharmony_ci};
133f08c3bdfSopenharmony_ci
134f08c3bdfSopenharmony_ciint TST_TOTAL = sizeof(test_data) / sizeof(test_data[0]);
135f08c3bdfSopenharmony_ciint block_size;
136f08c3bdfSopenharmony_ciint buf_size;
137f08c3bdfSopenharmony_ci
138f08c3bdfSopenharmony_ci/******************************************************************************
139f08c3bdfSopenharmony_ci * Performs all one time clean up for this test on successful
140f08c3bdfSopenharmony_ci * completion,  premature exit or  failure. Closes all temporary
141f08c3bdfSopenharmony_ci * files, removes all temporary directories exits the test with
142f08c3bdfSopenharmony_ci * appropriate return code by calling tst_exit() function.
143f08c3bdfSopenharmony_ci******************************************************************************/
144f08c3bdfSopenharmony_civoid cleanup(void)
145f08c3bdfSopenharmony_ci{
146f08c3bdfSopenharmony_ci	/* Close all open file descriptors. */
147f08c3bdfSopenharmony_ci	if (close(fd) == -1)
148f08c3bdfSopenharmony_ci		tst_resm(TWARN | TERRNO, "close(%s) failed", fname);
149f08c3bdfSopenharmony_ci
150f08c3bdfSopenharmony_ci	tst_rmdir();
151f08c3bdfSopenharmony_ci
152f08c3bdfSopenharmony_ci}
153f08c3bdfSopenharmony_ci
154f08c3bdfSopenharmony_ci/*****************************************************************************
155f08c3bdfSopenharmony_ci * Performs all one time setup for this test. This function is
156f08c3bdfSopenharmony_ci * used to create temporary dirs and temporary files
157f08c3bdfSopenharmony_ci * that may be used in the course of this test
158f08c3bdfSopenharmony_ci ******************************************************************************/
159f08c3bdfSopenharmony_ci
160f08c3bdfSopenharmony_civoid setup(void)
161f08c3bdfSopenharmony_ci{
162f08c3bdfSopenharmony_ci	/* Create temporary directories */
163f08c3bdfSopenharmony_ci	TEST_PAUSE;
164f08c3bdfSopenharmony_ci
165f08c3bdfSopenharmony_ci	tst_tmpdir();
166f08c3bdfSopenharmony_ci
167f08c3bdfSopenharmony_ci	sprintf(fname, "tfile_sparse_%d", getpid());
168f08c3bdfSopenharmony_ci	fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0700);
169f08c3bdfSopenharmony_ci	get_blocksize(fd);
170f08c3bdfSopenharmony_ci	populate_file();
171f08c3bdfSopenharmony_ci	file_seek(BLOCKS_WRITTEN + HOLE_SIZE_IN_BLOCKS);	/* create holes */
172f08c3bdfSopenharmony_ci	populate_file();
173f08c3bdfSopenharmony_ci	file_seek(0);		/* Rewind */
174f08c3bdfSopenharmony_ci}
175f08c3bdfSopenharmony_ci
176f08c3bdfSopenharmony_ci/*****************************************************************************
177f08c3bdfSopenharmony_ci * Gets the block size for the file system
178f08c3bdfSopenharmony_ci ******************************************************************************/
179f08c3bdfSopenharmony_civoid get_blocksize(int fd)
180f08c3bdfSopenharmony_ci{
181f08c3bdfSopenharmony_ci	struct stat file_stat;
182f08c3bdfSopenharmony_ci
183f08c3bdfSopenharmony_ci	if (fstat(fd, &file_stat) < 0)
184f08c3bdfSopenharmony_ci		tst_resm(TFAIL | TERRNO,
185f08c3bdfSopenharmony_ci			 "fstat failed while getting block_size");
186f08c3bdfSopenharmony_ci
187f08c3bdfSopenharmony_ci	block_size = (int)file_stat.st_blksize;
188f08c3bdfSopenharmony_ci	buf_size = block_size;
189f08c3bdfSopenharmony_ci}
190f08c3bdfSopenharmony_ci
191f08c3bdfSopenharmony_ci/*****************************************************************************
192f08c3bdfSopenharmony_ci * Create a Hole in the file
193f08c3bdfSopenharmony_ci ******************************************************************************/
194f08c3bdfSopenharmony_civoid file_seek(off_t offset)
195f08c3bdfSopenharmony_ci{
196f08c3bdfSopenharmony_ci	offset *= block_size;
197f08c3bdfSopenharmony_ci	lseek(fd, offset, SEEK_SET);
198f08c3bdfSopenharmony_ci}
199f08c3bdfSopenharmony_ci
200f08c3bdfSopenharmony_ci/*****************************************************************************
201f08c3bdfSopenharmony_ci * Writes data into the file
202f08c3bdfSopenharmony_ci ******************************************************************************/
203f08c3bdfSopenharmony_civoid populate_file(void)
204f08c3bdfSopenharmony_ci{
205f08c3bdfSopenharmony_ci	char buf[buf_size + 1];
206f08c3bdfSopenharmony_ci	int index;
207f08c3bdfSopenharmony_ci	int blocks;
208f08c3bdfSopenharmony_ci	int data;
209f08c3bdfSopenharmony_ci	for (blocks = 0; blocks < BLOCKS_WRITTEN; blocks++) {
210f08c3bdfSopenharmony_ci		for (index = 0; index < buf_size; index++)
211f08c3bdfSopenharmony_ci			buf[index] = 'A' + (index % 26);
212f08c3bdfSopenharmony_ci		buf[buf_size] = '\0';
213f08c3bdfSopenharmony_ci		if ((data = write(fd, buf, buf_size)) < 0)
214f08c3bdfSopenharmony_ci			tst_brkm(TBROK | TERRNO, cleanup,
215f08c3bdfSopenharmony_ci				 "Unable to write to %s", fname);
216f08c3bdfSopenharmony_ci	}
217f08c3bdfSopenharmony_ci}
218f08c3bdfSopenharmony_ci
219f08c3bdfSopenharmony_ci/*****************************************************************************
220f08c3bdfSopenharmony_ci * Main function that calls the system call with the  appropriate parameters
221f08c3bdfSopenharmony_ci ******************************************************************************/
222f08c3bdfSopenharmony_ci/* ac: number of command line parameters */
223f08c3bdfSopenharmony_ci/* av: pointer to the array of the command line parameters */
224f08c3bdfSopenharmony_ciint main(int ac, char **av)
225f08c3bdfSopenharmony_ci{
226f08c3bdfSopenharmony_ci	int test_index = 0;
227f08c3bdfSopenharmony_ci	int lc;
228f08c3bdfSopenharmony_ci
229f08c3bdfSopenharmony_ci	/***************************************************************
230f08c3bdfSopenharmony_ci	 * parse standard options
231f08c3bdfSopenharmony_ci	***************************************************************/
232f08c3bdfSopenharmony_ci	tst_parse_opts(ac, av, NULL, NULL);
233f08c3bdfSopenharmony_ci
234f08c3bdfSopenharmony_ci	/* perform global test setup, call setup() function */
235f08c3bdfSopenharmony_ci	setup();
236f08c3bdfSopenharmony_ci
237f08c3bdfSopenharmony_ci	for (lc = 0; TEST_LOOPING(lc); lc++) {
238f08c3bdfSopenharmony_ci		/* reset tst_count in case we are looping */
239f08c3bdfSopenharmony_ci		tst_count = 0;
240f08c3bdfSopenharmony_ci		for (test_index = 0; test_index < TST_TOTAL; test_index++) {
241f08c3bdfSopenharmony_ci			TEST(fallocate
242f08c3bdfSopenharmony_ci			     (fd, test_data[test_index].mode,
243f08c3bdfSopenharmony_ci			      test_data[test_index].offset * block_size,
244f08c3bdfSopenharmony_ci			      test_data[test_index].len * block_size));
245f08c3bdfSopenharmony_ci
246f08c3bdfSopenharmony_ci			/* check return code */
247f08c3bdfSopenharmony_ci			if (TEST_RETURN != test_data[test_index].error) {
248f08c3bdfSopenharmony_ci				if (TEST_ERRNO == EOPNOTSUPP
249f08c3bdfSopenharmony_ci				    || TEST_ERRNO == ENOSYS) {
250f08c3bdfSopenharmony_ci					tst_brkm(TCONF, cleanup,
251f08c3bdfSopenharmony_ci						 "fallocate system call is not implemented");
252f08c3bdfSopenharmony_ci				}
253f08c3bdfSopenharmony_ci				tst_resm(TFAIL | TTERRNO,
254f08c3bdfSopenharmony_ci					 "fallocate(%s, %d, %" PRId64 ", %"
255f08c3bdfSopenharmony_ci					 PRId64 ") failed", fname,
256f08c3bdfSopenharmony_ci					 test_data[test_index].mode,
257f08c3bdfSopenharmony_ci					 test_data[test_index].offset *
258f08c3bdfSopenharmony_ci					 block_size,
259f08c3bdfSopenharmony_ci					 test_data[test_index].len *
260f08c3bdfSopenharmony_ci					 block_size);
261f08c3bdfSopenharmony_ci			} else {
262f08c3bdfSopenharmony_ci				tst_resm(TPASS,
263f08c3bdfSopenharmony_ci					 "fallocate(%s, %d, %" PRId64
264f08c3bdfSopenharmony_ci					 ", %" PRId64 ") returned %ld",
265f08c3bdfSopenharmony_ci					 fname,
266f08c3bdfSopenharmony_ci					 test_data[test_index].mode,
267f08c3bdfSopenharmony_ci					 test_data[test_index].offset *
268f08c3bdfSopenharmony_ci					 block_size,
269f08c3bdfSopenharmony_ci					 test_data[test_index].len *
270f08c3bdfSopenharmony_ci					 block_size, TEST_RETURN);
271f08c3bdfSopenharmony_ci			}
272f08c3bdfSopenharmony_ci		}
273f08c3bdfSopenharmony_ci	}
274f08c3bdfSopenharmony_ci
275f08c3bdfSopenharmony_ci	cleanup();
276f08c3bdfSopenharmony_ci	tst_exit();
277f08c3bdfSopenharmony_ci}
278