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