blob: 6270e371fa648f44ee7745d1ecc144e912f8cdc0 [file] [log] [blame]
subrata_modak122c6032008-01-08 11:01:11 +00001/******************************************************************************
subrata_modak56207ce2009-03-23 13:35:39 +00002 * fallocate01.c
subrata_modak122c6032008-01-08 11:01:11 +00003 * Mon Dec 24 2007
subrata_modak56207ce2009-03-23 13:35:39 +00004 * Copyright (c) International Business Machines Corp., 2007
subrata_modak122c6032008-01-08 11:01:11 +00005 * Emali : sharyathi@in.ibm.com
6 ******************************************************************************/
7
subrata_modak122c6032008-01-08 11:01:11 +00008/***************************************************************************
subrata_modak56207ce2009-03-23 13:35:39 +00009 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22***************************************************************************/
subrata_modak122c6032008-01-08 11:01:11 +000023
24/*****************************************************************************
subrata_modak56207ce2009-03-23 13:35:39 +000025 *
26 * OS Test - International Business Machines Corp. 2007.
27 *
28 * TEST IDENTIFIER : fallocate01
29 *
30 * EXECUTED BY : anyone
31 *
32 * TEST TITLE : Basic test for fallocate()
33 *
34 * TEST CASE TOTAL : 2
35 *
36 * CPU ARCHITECTURES : PPC,X86, X86_64
37 *
38 * AUTHOR : Sharyathi Nagesh
39 *
40 * CO-PILOT :
41 *
42 * DATE STARTED : 24/12/2007
43 *
44 * TEST CASES
45 * (Working of fallocate under 2 modes)
46 * 1) DEFAULT 2)FALLOC_FL_KEEP_SIZE
47 *
48 * INPUT SPECIFICATIONS
49 * No input needs to be specified
50 * fallocate() in puts are generated randomly
51 *
52 * OUTPUT SPECIFICATIONS
53 * Output describing whether test cases passed or failed.
54 *
55 * ENVIRONMENTAL NEEDS
56 * Test Needs to be executed on file system supporting ext4
57 * LTP {TMP} Needs to be set to such a folder
58 *
59 * SPECIAL PROCEDURAL REQUIREMENTS
60 * None
61 *
62 * DETAILED DESCRIPTION
63 * This is a test case for fallocate() system call.
64 * This test suite tests basic working of fallocate under different modes
65 * It trys to fallocate memory blocks and write into that block
66 *
67 * Total 2 Test Cases :-
68 * (1) Test Case for DEFAULT MODE
69 * (2) Test Case for FALLOC_FL_KEEP_SIZE
70 *
71 * Setup:
72 * Setup file on which fallocate is to be called
73 * Set up 2 files for each mode
74 *
75 * Test:
76 * Loop if the proper options are given.
77 * Execute system call
78 * Check return code, if system call did fail
79 * lseek to some random location with in allocate block
80 * write data into the locattion Report if any error encountered
81 * PASS the test otherwise
82 *
83 * Cleanup:
84 * Cleanup the temporary folder
85 *
subrata_modak122c6032008-01-08 11:01:11 +000086*************************************************************************/
87
88/* Standard Include Files */
89#include <stdio.h>
90#include <stdlib.h>
Garrett Cooper187f2512010-12-19 18:07:59 -080091#include <endian.h>
subrata_modak122c6032008-01-08 11:01:11 +000092#include <errno.h>
93#include <sys/stat.h>
94#include <sys/types.h>
95#include <fcntl.h>
96#include <sys/syscall.h>
97#include <unistd.h>
98#include <error.h>
vapier4a5373f2009-08-28 12:40:49 +000099#include <inttypes.h>
subrata_modakdf18bd02008-02-19 09:32:47 +0000100#include <sys/utsname.h>
subrata_modak122c6032008-01-08 11:01:11 +0000101
102/* Harness Specific Include Files. */
103#include "test.h"
104#include "usctest.h"
105#include "linux_syscall_numbers.h"
106
subrata_modak122c6032008-01-08 11:01:11 +0000107#define BLOCKS_WRITTEN 12
108
subrata_modak122c6032008-01-08 11:01:11 +0000109/* Local Function */
110static inline long fallocate();
111void get_blocksize(int);
112void populate_files(int fd);
subrata_modak56207ce2009-03-23 13:35:39 +0000113void runtest(int, int, loff_t);
subrata_modak122c6032008-01-08 11:01:11 +0000114
subrata_modak56207ce2009-03-23 13:35:39 +0000115char *TCID = "fallocate01"; /* test program identifier */
116char fname_mode1[255], fname_mode2[255]; /* Files used for testing */
subrata_modak122c6032008-01-08 11:01:11 +0000117int fd_mode1, fd_mode2;
Garrett Cooper8dca4222010-12-18 03:57:35 -0800118int TST_TOTAL = 2;
119loff_t block_size;
subrata_modak122c6032008-01-08 11:01:11 +0000120int buf_size;
121
122/******************************************************************************
subrata_modak56207ce2009-03-23 13:35:39 +0000123 * Performs all one time clean up for this test on successful
subrata_modak4bb656a2009-02-26 12:02:09 +0000124 * completion, premature exit or failure. Closes all temporary
subrata_modak56207ce2009-03-23 13:35:39 +0000125 * files, removes all temporary directories exits the test with
126 * appropriate return code by calling tst_exit() function.
subrata_modak122c6032008-01-08 11:01:11 +0000127******************************************************************************/
Garrett Cooper8dca4222010-12-18 03:57:35 -0800128void cleanup()
subrata_modak122c6032008-01-08 11:01:11 +0000129{
subrata_modak122c6032008-01-08 11:01:11 +0000130
vapier4a5373f2009-08-28 12:40:49 +0000131 if (close(fd_mode1) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800132 tst_resm(TWARN | TERRNO, "close(%s) failed", fname_mode1);
vapier4a5373f2009-08-28 12:40:49 +0000133 if (close(fd_mode2) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134 tst_resm(TWARN | TERRNO, "close(%s) failed", fname_mode2);
subrata_modak122c6032008-01-08 11:01:11 +0000135 tst_rmdir();
subrata_modak122c6032008-01-08 11:01:11 +0000136}
137
subrata_modak122c6032008-01-08 11:01:11 +0000138/*****************************************************************************
Garrett Cooper2c282152010-12-16 00:55:50 -0800139 * Performs all one time setup for this test. This function is
subrata_modak122c6032008-01-08 11:01:11 +0000140 * used to create temporary dirs and temporary files
141 * that may be used in the course of this test
142 ******************************************************************************/
subrata_modak56207ce2009-03-23 13:35:39 +0000143void setup()
subrata_modak122c6032008-01-08 11:01:11 +0000144{
subrata_modak122c6032008-01-08 11:01:11 +0000145 /* Create temporary directories */
146 TEST_PAUSE;
147
148 tst_tmpdir();
subrata_modakbdbaec52009-02-26 12:14:51 +0000149
subrata_modak56207ce2009-03-23 13:35:39 +0000150 sprintf(fname_mode1, "tfile_mode1_%d", getpid());
vapier4a5373f2009-08-28 12:40:49 +0000151 fd_mode1 = open(fname_mode1, O_RDWR | O_CREAT, 0700);
152 if (fd_mode1 == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800153 tst_brkm(TBROK | TERRNO, cleanup, "open(%s, O_RDWR) failed",
154 fname_mode1);
subrata_modak122c6032008-01-08 11:01:11 +0000155 get_blocksize(fd_mode1);
subrata_modak122c6032008-01-08 11:01:11 +0000156 populate_files(fd_mode1);
vapier4a5373f2009-08-28 12:40:49 +0000157
subrata_modak56207ce2009-03-23 13:35:39 +0000158 sprintf(fname_mode2, "tfile_mode2_%d", getpid());
Wanlong Gao354ebb42012-12-07 10:10:04 +0800159 fd_mode2 = open(fname_mode2, O_RDWR | O_CREAT, 0700);
vapier4a5373f2009-08-28 12:40:49 +0000160 if (fd_mode2 == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800161 tst_brkm(TBROK | TERRNO, cleanup, "open(%s, O_RDWR) failed",
162 fname_mode2);
subrata_modak122c6032008-01-08 11:01:11 +0000163 populate_files(fd_mode2);
subrata_modak122c6032008-01-08 11:01:11 +0000164}
165
166/*****************************************************************************
167 * Gets the block size for the file system
168 ******************************************************************************/
subrata_modak56207ce2009-03-23 13:35:39 +0000169void get_blocksize(int fd)
subrata_modak122c6032008-01-08 11:01:11 +0000170{
subrata_modak56207ce2009-03-23 13:35:39 +0000171 struct stat file_stat;
subrata_modak122c6032008-01-08 11:01:11 +0000172
subrata_modak56207ce2009-03-23 13:35:39 +0000173 if (fstat(fd, &file_stat) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800174 tst_resm(TFAIL | TERRNO,
175 "fstat failed while getting block_size");
subrata_modak122c6032008-01-08 11:01:11 +0000176
Garrett Cooper8dca4222010-12-18 03:57:35 -0800177 block_size = file_stat.st_blksize;
subrata_modak56207ce2009-03-23 13:35:39 +0000178 buf_size = block_size;
subrata_modak122c6032008-01-08 11:01:11 +0000179}
subrata_modak56207ce2009-03-23 13:35:39 +0000180
subrata_modak122c6032008-01-08 11:01:11 +0000181/*****************************************************************************
182 * Writes data into the file
183 ******************************************************************************/
184
subrata_modak56207ce2009-03-23 13:35:39 +0000185void populate_files(int fd)
subrata_modak122c6032008-01-08 11:01:11 +0000186{
187 char buf[buf_size + 1];
188 char *fname;
189 int index;
190 int blocks;
191 int data;
192
subrata_modak56207ce2009-03-23 13:35:39 +0000193 if (fd == fd_mode1)
subrata_modak122c6032008-01-08 11:01:11 +0000194 fname = fname_mode1;
195 else
196 fname = fname_mode2;
197
subrata_modak56207ce2009-03-23 13:35:39 +0000198 for (blocks = 0; blocks < BLOCKS_WRITTEN; blocks++) {
subrata_modak4bb656a2009-02-26 12:02:09 +0000199 for (index = 0; index < buf_size; index++)
subrata_modak56207ce2009-03-23 13:35:39 +0000200 buf[index] = 'A' + (index % 26);
201 buf[buf_size] = '\0';
Garrett Cooper8dca4222010-12-18 03:57:35 -0800202 if ((data = write(fd, buf, buf_size)) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800203 tst_brkm(TBROK | TERRNO, cleanup, "write failed");
subrata_modak122c6032008-01-08 11:01:11 +0000204 }
205}
206
subrata_modak56207ce2009-03-23 13:35:39 +0000207int main(int ac, char **av)
subrata_modak122c6032008-01-08 11:01:11 +0000208{
209 int fd;
subrata_modak56207ce2009-03-23 13:35:39 +0000210 enum { DEFAULT, FALLOC_FL_KEEP_SIZE } mode;
subrata_modak122c6032008-01-08 11:01:11 +0000211 loff_t expected_size;
212 int lc;
213 char *msg;
214
Garrett Cooper45e285d2010-11-22 12:19:25 -0800215 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800216 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakbdbaec52009-02-26 12:14:51 +0000217
subrata_modak122c6032008-01-08 11:01:11 +0000218 setup();
subrata_modakbdbaec52009-02-26 12:14:51 +0000219
subrata_modak56207ce2009-03-23 13:35:39 +0000220 for (lc = 0; TEST_LOOPING(lc); lc++) {
Garrett Cooper2c282152010-12-16 00:55:50 -0800221
subrata_modak56207ce2009-03-23 13:35:39 +0000222 Tst_count = 0;
subrata_modak122c6032008-01-08 11:01:11 +0000223
subrata_modak56207ce2009-03-23 13:35:39 +0000224 for (mode = DEFAULT; mode <= FALLOC_FL_KEEP_SIZE; mode++) {
225 switch (mode) {
226 case DEFAULT:
227 fd = fd_mode1;
228 expected_size =
229 BLOCKS_WRITTEN * block_size + block_size;
subrata_modak122c6032008-01-08 11:01:11 +0000230 break;
subrata_modak56207ce2009-03-23 13:35:39 +0000231 case FALLOC_FL_KEEP_SIZE:
232 fd = fd_mode2;
subrata_modak4bb656a2009-02-26 12:02:09 +0000233 expected_size = BLOCKS_WRITTEN * block_size;
subrata_modak122c6032008-01-08 11:01:11 +0000234 break;
subrata_modak56207ce2009-03-23 13:35:39 +0000235 }
subrata_modak122c6032008-01-08 11:01:11 +0000236 runtest(mode, fd, expected_size);
237 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000238 }
subrata_modak122c6032008-01-08 11:01:11 +0000239
240 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800241 tst_exit();
subrata_modak122c6032008-01-08 11:01:11 +0000242}
243
subrata_modak122c6032008-01-08 11:01:11 +0000244static inline long fallocate(int fd, int mode, loff_t offset, loff_t len)
245{
subrata_modak56207ce2009-03-23 13:35:39 +0000246#if __WORDSIZE == 32
Jan Stancek359980f2013-02-15 10:16:05 +0100247 return (long)ltp_syscall(__NR_fallocate, fd, mode,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800248 __LONG_LONG_PAIR((off_t) (offset >> 32),
249 (off_t) offset),
250 __LONG_LONG_PAIR((off_t) (len >> 32),
251 (off_t) len));
Garrett Cooper187f2512010-12-19 18:07:59 -0800252#else
Jan Stancek359980f2013-02-15 10:16:05 +0100253 return ltp_syscall(__NR_fallocate, fd, mode, offset, len);
Garrett Cooper187f2512010-12-19 18:07:59 -0800254#endif
subrata_modak122c6032008-01-08 11:01:11 +0000255}
256
257/*****************************************************************************
258 * Calls the system call, with appropriate parameters and writes data
259 ******************************************************************************/
subrata_modak56207ce2009-03-23 13:35:39 +0000260void runtest(int mode, int fd, loff_t expected_size)
subrata_modak122c6032008-01-08 11:01:11 +0000261{
262 loff_t offset;
263 loff_t len = block_size;
264 loff_t write_offset, lseek_offset;
subrata_modak56207ce2009-03-23 13:35:39 +0000265 offset = lseek(fd, 0, SEEK_END);
subrata_modak122c6032008-01-08 11:01:11 +0000266 struct stat file_stat;
267 errno = 0;
subrata_modak56207ce2009-03-23 13:35:39 +0000268
269 TEST(fallocate(fd, mode, offset, len));
270 /* check return code */
271 if (TEST_RETURN != 0) {
vapier6dd41a32009-11-04 16:31:05 +0000272 if (TEST_ERRNO == EOPNOTSUPP || TEST_ERRNO == ENOSYS) {
subrata_modak56207ce2009-03-23 13:35:39 +0000273 tst_brkm(TCONF, cleanup,
vapier4a5373f2009-08-28 12:40:49 +0000274 "fallocate system call is not implemented");
subrata_modak122c6032008-01-08 11:01:11 +0000275 }
subrata_modak56207ce2009-03-23 13:35:39 +0000276 TEST_ERROR_LOG(TEST_ERRNO);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800277 tst_resm(TFAIL | TTERRNO,
278 "fallocate(%d, %d, %" PRId64 ", %" PRId64 ") failed",
vapier4a5373f2009-08-28 12:40:49 +0000279 fd, mode, offset, len);
subrata_modak56207ce2009-03-23 13:35:39 +0000280 return;
281 } else {
282 if (STD_FUNCTIONAL_TEST) {
283 /* No Verification test, yet... */
284 tst_resm(TPASS,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800285 "fallocate(%d, %d, %" PRId64 ", %" PRId64
286 ") returned %ld", fd, mode, offset, len,
287 TEST_RETURN);
subrata_modak56207ce2009-03-23 13:35:39 +0000288 }
subrata_modak122c6032008-01-08 11:01:11 +0000289 }
subrata_modakbdbaec52009-02-26 12:14:51 +0000290
subrata_modak56207ce2009-03-23 13:35:39 +0000291 if (fstat(fd, &file_stat) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800292 tst_resm(TFAIL | TERRNO, "fstat failed after fallocate()");
subrata_modakbdbaec52009-02-26 12:14:51 +0000293
subrata_modak56207ce2009-03-23 13:35:39 +0000294 if (file_stat.st_size != expected_size)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800295 tst_resm(TFAIL | TTERRNO,
296 "fstat test fails on fallocate (%d, %d, %" PRId64 ", %"
297 PRId64 ") Failed on mode", fd, mode, offset, len);
subrata_modakbdbaec52009-02-26 12:14:51 +0000298
subrata_modak122c6032008-01-08 11:01:11 +0000299 write_offset = random() % len;
subrata_modak56207ce2009-03-23 13:35:39 +0000300 lseek_offset = lseek(fd, write_offset, SEEK_CUR);
301 if (lseek_offset != offset + write_offset) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800302 tst_resm(TFAIL | TTERRNO,
303 "lseek fails in fallocate(%d, %d, %" PRId64 ", %"
304 PRId64 ") failed on mode", fd, mode, offset, len);
subrata_modak122c6032008-01-08 11:01:11 +0000305 return;
306 }
subrata_modak122c6032008-01-08 11:01:11 +0000307 //Write a character to file at random location
subrata_modak56207ce2009-03-23 13:35:39 +0000308 TEST(write(fd, "A", 1));
309 /* check return code */
310 if (TEST_RETURN == -1) {
311 TEST_ERROR_LOG(TEST_ERRNO);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800312 tst_resm(TFAIL | TTERRNO,
313 "write fails in fallocate(%d, %d, %" PRId64 ", %"
314 PRId64 ") failed", fd, mode, offset, len);
subrata_modak56207ce2009-03-23 13:35:39 +0000315 } else {
316 if (STD_FUNCTIONAL_TEST) {
317 /* No Verification test, yet... */
318 tst_resm(TPASS,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800319 "write operation on fallocated(%d, %d, %"
320 PRId64 ", %" PRId64 ") returned %ld", fd, mode,
321 offset, len, TEST_RETURN);
subrata_modak56207ce2009-03-23 13:35:39 +0000322 }
subrata_modak122c6032008-01-08 11:01:11 +0000323 }
Garrett Cooper187f2512010-12-19 18:07:59 -0800324}