1f08c3bdfSopenharmony_ci/******************************************************************************
2f08c3bdfSopenharmony_ci *	Copyright (c) International Business Machines  Corp., 2007
3f08c3bdfSopenharmony_ci *	Author: Sharyathi Nagesh <sharyathi@in.ibm.com>
4f08c3bdfSopenharmony_ci ******************************************************************************/
5f08c3bdfSopenharmony_ci
6f08c3bdfSopenharmony_ci/***************************************************************************
7f08c3bdfSopenharmony_ci * This program is free software;  you can redistribute it and/or modify
8f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by
9f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or
10f08c3bdfSopenharmony_ci * (at your option) any later version.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful,
13f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15f08c3bdfSopenharmony_ci * GNU Library General Public License for more details.
16f08c3bdfSopenharmony_ci *
17f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License
18f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software
19f08c3bdfSopenharmony_ci * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20f08c3bdfSopenharmony_ci***************************************************************************/
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_ci/*
23f08c3bdfSopenharmony_ci * DESCRIPTION
24f08c3bdfSopenharmony_ci *	check fallocate() with various error conditions that should produce
25f08c3bdfSopenharmony_ci *	EBADF, EINVAL and EFBIG.
26f08c3bdfSopenharmony_ci */
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_ci#define _GNU_SOURCE
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci#include <stdio.h>
31f08c3bdfSopenharmony_ci#include <stdlib.h>
32f08c3bdfSopenharmony_ci#include <endian.h>
33f08c3bdfSopenharmony_ci#include <errno.h>
34f08c3bdfSopenharmony_ci#include <sys/stat.h>
35f08c3bdfSopenharmony_ci#include <sys/types.h>
36f08c3bdfSopenharmony_ci#include <fcntl.h>
37f08c3bdfSopenharmony_ci#include <inttypes.h>
38f08c3bdfSopenharmony_ci#include <sys/utsname.h>
39f08c3bdfSopenharmony_ci#include <limits.h>
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci#include "test.h"
42f08c3bdfSopenharmony_ci#include "safe_macros.h"
43f08c3bdfSopenharmony_ci#include "lapi/fallocate.h"
44f08c3bdfSopenharmony_ci#include "lapi/abisize.h"
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci#define BLOCKS_WRITTEN		12
47f08c3bdfSopenharmony_ci#ifdef TEST_DEFAULT
48f08c3bdfSopenharmony_ci# define DEFAULT_TEST_MODE	0
49f08c3bdfSopenharmony_ci#else
50f08c3bdfSopenharmony_ci# define DEFAULT_TEST_MODE	1
51f08c3bdfSopenharmony_ci#endif
52f08c3bdfSopenharmony_ci#define OFFSET			12
53f08c3bdfSopenharmony_ci#define FNAMER			"test_file1"
54f08c3bdfSopenharmony_ci#define FNAMEW			"test_file2"
55f08c3bdfSopenharmony_ci#define BLOCK_SIZE		1024
56f08c3bdfSopenharmony_ci#define MAX_FILESIZE            (LLONG_MAX / 1024)
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_cistatic void setup(void);
59f08c3bdfSopenharmony_cistatic void fallocate_verify(int);
60f08c3bdfSopenharmony_cistatic void cleanup(void);
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_cistatic int fdw;
63f08c3bdfSopenharmony_cistatic int fdr;
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_cistatic struct test_data_t {
66f08c3bdfSopenharmony_ci	int *fd;
67f08c3bdfSopenharmony_ci	char *fname;
68f08c3bdfSopenharmony_ci	int mode;
69f08c3bdfSopenharmony_ci	loff_t offset;
70f08c3bdfSopenharmony_ci	loff_t len;
71f08c3bdfSopenharmony_ci	int error;
72f08c3bdfSopenharmony_ci} test_data[] = {
73f08c3bdfSopenharmony_ci	{&fdr, FNAMER, DEFAULT_TEST_MODE, 0, 1, EBADF},
74f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, -1, 1, EINVAL},
75f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, 1, -1, EINVAL},
76f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, BLOCKS_WRITTEN, 0, EINVAL},
77f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, BLOCKS_WRITTEN, -1, EINVAL},
78f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, -(BLOCKS_WRITTEN+OFFSET), 1, EINVAL},
79f08c3bdfSopenharmony_ci#if defined(TST_ABI64) || _FILE_OFFSET_BITS == 64
80f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, MAX_FILESIZE, 1, EFBIG},
81f08c3bdfSopenharmony_ci	{&fdw, FNAMEW, DEFAULT_TEST_MODE, 1, MAX_FILESIZE, EFBIG},
82f08c3bdfSopenharmony_ci#endif
83f08c3bdfSopenharmony_ci};
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ciTCID_DEFINE(fallocate02);
86f08c3bdfSopenharmony_ciint TST_TOTAL = ARRAY_SIZE(test_data);
87f08c3bdfSopenharmony_ci
88f08c3bdfSopenharmony_ciint main(int ac, char **av)
89f08c3bdfSopenharmony_ci{
90f08c3bdfSopenharmony_ci	int lc;
91f08c3bdfSopenharmony_ci	int i;
92f08c3bdfSopenharmony_ci
93f08c3bdfSopenharmony_ci	tst_parse_opts(ac, av, NULL, NULL);
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci	setup();
96f08c3bdfSopenharmony_ci
97f08c3bdfSopenharmony_ci	for (lc = 0; TEST_LOOPING(lc); lc++) {
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ci		tst_count = 0;
100f08c3bdfSopenharmony_ci
101f08c3bdfSopenharmony_ci		for (i = 0; i < TST_TOTAL; i++)
102f08c3bdfSopenharmony_ci			fallocate_verify(i);
103f08c3bdfSopenharmony_ci	}
104f08c3bdfSopenharmony_ci
105f08c3bdfSopenharmony_ci	cleanup();
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci	tst_exit();
108f08c3bdfSopenharmony_ci}
109f08c3bdfSopenharmony_ci
110f08c3bdfSopenharmony_cistatic void setup(void)
111f08c3bdfSopenharmony_ci{
112f08c3bdfSopenharmony_ci	int i;
113f08c3bdfSopenharmony_ci
114f08c3bdfSopenharmony_ci	tst_sig(NOFORK, DEF_HANDLER, cleanup);
115f08c3bdfSopenharmony_ci
116f08c3bdfSopenharmony_ci	TEST_PAUSE;
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_ci	tst_tmpdir();
119f08c3bdfSopenharmony_ci
120f08c3bdfSopenharmony_ci	fdr = SAFE_OPEN(cleanup, FNAMER, O_RDONLY | O_CREAT, S_IRUSR);
121f08c3bdfSopenharmony_ci
122f08c3bdfSopenharmony_ci	fdw = SAFE_OPEN(cleanup, FNAMEW, O_RDWR | O_CREAT, S_IRWXU);
123f08c3bdfSopenharmony_ci
124f08c3bdfSopenharmony_ci	char buf[BLOCK_SIZE];
125f08c3bdfSopenharmony_ci	memset(buf, 'A', BLOCK_SIZE);
126f08c3bdfSopenharmony_ci	for (i = 0; i < BLOCKS_WRITTEN; i++)
127f08c3bdfSopenharmony_ci		SAFE_WRITE(cleanup, SAFE_WRITE_ALL, fdw, buf, BLOCK_SIZE);
128f08c3bdfSopenharmony_ci}
129f08c3bdfSopenharmony_ci
130f08c3bdfSopenharmony_cistatic void fallocate_verify(int i)
131f08c3bdfSopenharmony_ci{
132f08c3bdfSopenharmony_ci	TEST(fallocate(*test_data[i].fd, test_data[i].mode,
133f08c3bdfSopenharmony_ci		       test_data[i].offset * BLOCK_SIZE,
134f08c3bdfSopenharmony_ci		       test_data[i].len * BLOCK_SIZE));
135f08c3bdfSopenharmony_ci	if (TEST_ERRNO != test_data[i].error) {
136f08c3bdfSopenharmony_ci		if (TEST_ERRNO == EOPNOTSUPP ||
137f08c3bdfSopenharmony_ci		    TEST_ERRNO == ENOSYS) {
138f08c3bdfSopenharmony_ci			tst_brkm(TCONF, cleanup,
139f08c3bdfSopenharmony_ci				 "fallocate system call is not implemented");
140f08c3bdfSopenharmony_ci		}
141f08c3bdfSopenharmony_ci		tst_resm(TFAIL | TTERRNO,
142f08c3bdfSopenharmony_ci			 "fallocate(%s:%d, %d, %" PRId64 ", %" PRId64 ") "
143f08c3bdfSopenharmony_ci			 "failed, expected errno:%d", test_data[i].fname,
144f08c3bdfSopenharmony_ci			 *test_data[i].fd, test_data[i].mode,
145f08c3bdfSopenharmony_ci			 test_data[i].offset * BLOCK_SIZE,
146f08c3bdfSopenharmony_ci			 test_data[i].len * BLOCK_SIZE, test_data[i].error);
147f08c3bdfSopenharmony_ci	} else {
148f08c3bdfSopenharmony_ci		tst_resm(TPASS | TTERRNO,
149f08c3bdfSopenharmony_ci			 "fallocate(%s:%d, %d, %" PRId64 ", %" PRId64 ") "
150f08c3bdfSopenharmony_ci			 "returned %d", test_data[i].fname, *test_data[i].fd,
151f08c3bdfSopenharmony_ci			 test_data[i].mode, test_data[i].offset * BLOCK_SIZE,
152f08c3bdfSopenharmony_ci			 test_data[i].len * BLOCK_SIZE, TEST_ERRNO);
153f08c3bdfSopenharmony_ci	}
154f08c3bdfSopenharmony_ci}
155f08c3bdfSopenharmony_ci
156f08c3bdfSopenharmony_cistatic void cleanup(void)
157f08c3bdfSopenharmony_ci{
158f08c3bdfSopenharmony_ci	if (fdw > 0)
159f08c3bdfSopenharmony_ci		SAFE_CLOSE(NULL, fdw);
160f08c3bdfSopenharmony_ci	if (fdr > 0)
161f08c3bdfSopenharmony_ci		SAFE_CLOSE(NULL, fdr);
162f08c3bdfSopenharmony_ci
163f08c3bdfSopenharmony_ci	tst_rmdir();
164f08c3bdfSopenharmony_ci}
165