1 /****************************************************************************** 2 * sync_file_range01.c 3 * Copyright (c) International Business Machines Corp., 2008 4 * Email: bnpoorni (at) in.ibm.com 5 *****************************************************************************/ 6 7 /******************************************************************************/ 8 /* */ 9 /* 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 */ 17 /* the GNU 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 22 /* */ 23 /******************************************************************************/ 24 25 /***************************************************************************** 26 * TEST IDENTIFIER : sync_file_range01 $ 27 * $ 28 * EXECUTED BY : anyone $ 29 * 30 * TEST TITLE : Checks for Errors from sync_file_range() 31 * 32 * TEST CASE TOTAL : 5 33 * 34 * CPU ARCHITECTURES : All 35 * 36 * AUTHOR : B N Poornima 37 * 38 * DATE STARTED : 21/07/2008 39 * 40 * TEST CASES 41 * (Tests sync_file_range() for different test cases as reported in the man 42 * page) 43 * 44 * INPUT SPECIFICATIONS 45 * No input needs to be specified 46 * sync_file_data() in-puts are specified through test_data 47 * 48 * OUTPUT SPECIFICATIONS 49 * sync_file_data() error message matches with the expected error 50 * message. 51 * 52 * ENVIRONMENTAL NEEDS 53 * Kernel version 2.6.17 and above 54 * Kernel version 2.6.22 and above in case of PPC and PPC64 55 * 56 * SPECIAL PROCEDURAL REQUIREMENTS 57 * None 58 * 59 * DETAILED DESCRIPTION 60 * This is a test case for sync_file_range() system call. 61 * This test suite tests various error messages from the system call 62 * If the error message received matches with the expected 63 * test is considered passed else test fails 64 * 65 * Total 5 Test Cases :- 66 * Various error messages from the man page 67 * 68 * Setup: 69 * Setup files on which sync_file_range is to be called 70 * 71 * Test: 72 * Loop if the proper options are given. 73 * Execute system call 74 * Check return code. 75 * If error obtained matches with the expected error 76 * PASS the test, otherwise TEST FAILS 77 * 78 * Cleanup: 79 * Cleanup the temporary folder 80 * 81 ******************************************************************************/ 82 #define _GNU_SOURCE 83 84 #include <sys/types.h> 85 #include <sys/stat.h> 86 #include <sys/utsname.h> 87 #include <endian.h> 88 #include <errno.h> 89 #include <fcntl.h> 90 #include <stdio.h> 91 #include <stdlib.h> 92 #include <unistd.h> 93 94 #include "test.h" 95 #include "lapi/syscalls.h" 96 97 #ifndef SYNC_FILE_RANGE_WAIT_BEFORE 98 #define SYNC_FILE_RANGE_WAIT_BEFORE 1 99 #define SYNC_FILE_RANGE_WRITE 2 //DUMMY VALUES 100 #define SYNC_FILE_RANGE_WAIT_AFTER 4 101 #endif 102 103 #define SYNC_FILE_RANGE_INVALID 8 104 105 char *TCID = "sync_file_range01"; 106 char filename[255]; /* file used for testing */ 107 char spl_file[] = "/dev/null"; 108 int filed, sfd; /* normal and special fds */ 109 int bfd = -1; /* Bad file descriptor */ 110 111 struct test_data_t { 112 int *fd; 113 off64_t offset; 114 off64_t nbytes; 115 unsigned int flags; 116 int error; 117 } test_data[] = { 118 { 119 &bfd, 0, 1, SYNC_FILE_RANGE_WRITE, EBADF}, { 120 &sfd, 0, 1, SYNC_FILE_RANGE_WAIT_AFTER, ESPIPE}, { 121 &filed, -1, 1, SYNC_FILE_RANGE_WAIT_BEFORE, EINVAL}, { 122 &filed, 0, -1, SYNC_FILE_RANGE_WRITE, EINVAL}, { 123 &filed, 0, 1, SYNC_FILE_RANGE_INVALID, EINVAL} 124 }; 125 126 int TST_TOTAL = sizeof(test_data) / sizeof(test_data[0]); 127 128 /* Extern Global Functions */ 129 /******************************************************************************/ 130 /* */ 131 /* Function: cleanup */ 132 /* */ 133 /* Description: Performs all one time clean up for this test on successful */ 134 /* completion, premature exit or failure. Closes all temporary */ 135 /* files, removes all temporary directories exits the test with */ 136 /* appropriate return code by calling tst_exit() function. */ 137 /* */ 138 /* Input: None. */ 139 /* */ 140 /* Output: None. */ 141 /* */ 142 /* Return: On failure - Exits calling tst_exit(). Non '0' return code. */ 143 /* On success - Exits calling tst_exit(). With '0' return code. */ 144 /* */ 145 /******************************************************************************/ 146 void cleanup(void) 147 { 148 149 /* close the file we have open */ 150 if (close(filed) == -1) { 151 tst_resm(TWARN | TERRNO, "close(%s) failed", filename); 152 } 153 154 tst_rmdir(); 155 } 156 157 /* Local Functions */ 158 /******************************************************************************/ 159 /* */ 160 /* Function: setup */ 161 /* */ 162 /* Description: Performs all one time setup for this test. This function is */ 163 /* typically used to capture signals, create temporary dirs */ 164 /* and temporary files that may be used in the course of this */ 165 /* test. */ 166 /* */ 167 /* Input: None. */ 168 /* */ 169 /* Output: None. */ 170 /* */ 171 /* Return: On failure - Exits by calling cleanup(). */ 172 /* On success - returns 0. */ 173 /* */ 174 /******************************************************************************/ 175 void setup(void) 176 { 177 178 tst_sig(NOFORK, DEF_HANDLER, cleanup); 179 180 TEST_PAUSE; 181 182 tst_tmpdir(); 183 184 sprintf(filename, "tmpfile_%d", getpid()); 185 if ((filed = open(filename, O_RDWR | O_CREAT, 0700)) == -1) { 186 tst_brkm(TBROK | TERRNO, cleanup, 187 "open(%s, O_RDWR|O_CREAT,0700) failed", filename); 188 } 189 190 sfd = open(spl_file, O_RDWR | O_CREAT, 0700); 191 } 192 193 /***************************************************************************** 194 * Wraper function to call sync_file_range system call 195 ******************************************************************************/ 196 static inline long syncfilerange(int fd, off64_t offset, off64_t nbytes, 197 unsigned int flags) 198 { 199 /* arm and powerpc */ 200 #if (defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__)) 201 #if (__WORDSIZE == 32) 202 #if __BYTE_ORDER == __BIG_ENDIAN 203 return ltp_syscall(__NR_sync_file_range2, fd, flags, 204 (int)(offset >> 32), (int)offset, (int)(nbytes >> 32), 205 (int)nbytes); 206 #elif __BYTE_ORDER == __LITTLE_ENDIAN 207 return ltp_syscall(__NR_sync_file_range2, fd, flags, (int)offset, 208 (int)(offset >> 32), nbytes, (int)(nbytes >> 32)); 209 #endif 210 #else 211 return ltp_syscall(__NR_sync_file_range2, fd, flags, offset, nbytes); 212 #endif 213 214 /* s390 */ 215 #elif (defined(__s390__) || defined(__s390x__)) && __WORDSIZE == 32 216 return ltp_syscall(__NR_sync_file_range, fd, (int)(offset >> 32), 217 (int)offset, (int)(nbytes >> 32), (int)nbytes, flags); 218 219 /* mips */ 220 #elif defined(__mips__) && __WORDSIZE == 32 221 #if __BYTE_ORDER == __BIG_ENDIAN 222 return ltp_syscall(__NR_sync_file_range, fd, 0, (int)(offset >> 32), 223 (int)offset, (int)(nbytes >> 32), (int)nbytes, flags); 224 #elif __BYTE_ORDER == __LITTLE_ENDIAN 225 return ltp_syscall(__NR_sync_file_range, fd, 0, (int)offset, 226 (int)(offset >> 32), (int)nbytes, (int)(nbytes >> 32), flags); 227 #endif 228 229 /* other */ 230 #else 231 return ltp_syscall(__NR_sync_file_range, fd, offset, nbytes, flags); 232 #endif 233 } 234 235 /******************************************************************************/ 236 /* */ 237 /* Function: main */ 238 /* */ 239 /* Description: Entry point to this test-case. It parses all the command line */ 240 /* inputs, calls the global setup and executes the test. It logs */ 241 /* the test status and results appropriately using the LTP API's */ 242 /* On successful completion or premature failure, cleanup() func */ 243 /* is called and test exits with an appropriate return code. */ 244 /* */ 245 /* Input: Describe input arguments to this test-case */ 246 /* -l - Number of iteration */ 247 /* -v - Prints verbose output */ 248 /* -V - Prints the version number */ 249 /* */ 250 /* Exit: On failure - Exits by calling cleanup(). */ 251 /* On success - exits with 0 exit value. */ 252 /* */ 253 /******************************************************************************/ 254 int main(int ac, char **av) 255 { 256 257 int test_index = 0; 258 259 tst_parse_opts(ac, av, NULL, NULL); 260 261 #if defined(__powerpc__) || defined(__powerpc64__) /* for PPC, kernel version > 2.6.21 needed */ 262 if (tst_kvercmp(2, 16, 22) < 0) { 263 tst_brkm(TCONF, NULL, 264 "System doesn't support execution of the test"); 265 } 266 #else 267 /* For other archs, need kernel version > 2.6.16 */ 268 269 if (tst_kvercmp(2, 6, 17) < 0) { 270 tst_brkm(TCONF, NULL, 271 "System doesn't support execution of the test"); 272 } 273 #endif 274 275 setup(); 276 277 for (test_index = 0; test_index < TST_TOTAL; test_index++) { 278 TEST(syncfilerange 279 (*(test_data[test_index].fd), 280 test_data[test_index].offset, 281 test_data[test_index].nbytes, 282 test_data[test_index].flags)); 283 284 if (TEST_RETURN != -1) { 285 tst_resm(TFAIL, 286 "call succeeded unexpectedly (%ld != -1)", 287 TEST_RETURN); 288 continue; 289 } 290 291 if (TEST_ERRNO == test_data[test_index].error) { 292 tst_resm(TPASS | TTERRNO, "got expected error"); 293 } else { 294 tst_resm(TFAIL | TTERRNO, "got unexpected error; " 295 "expected %d", test_data[test_index].error); 296 } 297 298 } 299 300 cleanup(); 301 tst_exit(); 302 } 303