sync_file_range01.c revision 4548c6cf9bcdd96d8303caa4130ab638b61f8a30
1/****************************************************************************** 2 * sync_file_range01.c 3 * Copyright (c) International Business Machines Corp., 2008 4 * Email: bnpoorni@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/* Standard Include Files */ 85#include <sys/types.h> 86#include <sys/stat.h> 87#include <sys/utsname.h> 88#include <endian.h> 89#include <errno.h> 90#include <fcntl.h> 91#include <stdio.h> 92#include <stdlib.h> 93#include <unistd.h> 94 95/* Harness Specific Include Files. */ 96#include "test.h" 97#include "usctest.h" 98#include "linux_syscall_numbers.h" 99 100#ifndef SYNC_FILE_RANGE_WAIT_BEFORE 101#define SYNC_FILE_RANGE_WAIT_BEFORE 1 102#define SYNC_FILE_RANGE_WRITE 2 //DUMMY VALUES 103#define SYNC_FILE_RANGE_WAIT_AFTER 4 104#endif 105 106#define SYNC_FILE_RANGE_INVALID 8 107 108/* Extern Global Variables */ 109 110/* Global Variables */ 111char *TCID = "sync_file_range01"; /* test program identifier. */ 112char filename[255]; /* file used for testing */ 113char spl_file[] = "/dev/null"; 114int filed, sfd; /* normal and special fds */ 115int bfd = -1; /* Bad file descriptor */ 116 117struct test_data_t { 118 int *fd; 119 off64_t offset; 120 off64_t nbytes; 121 unsigned int flags; 122 int error; 123} test_data[] = { 124 { &bfd, 0, 1, SYNC_FILE_RANGE_WRITE, EBADF}, 125 { &sfd, 0, 1, SYNC_FILE_RANGE_WAIT_AFTER, ESPIPE}, 126 { &filed, -1, 1, SYNC_FILE_RANGE_WAIT_BEFORE, EINVAL}, 127 { &filed, 0, -1, SYNC_FILE_RANGE_WRITE, EINVAL}, 128 { &filed, 0, 1, SYNC_FILE_RANGE_INVALID, EINVAL} 129}; 130 131int TST_TOTAL = sizeof(test_data) / sizeof(test_data[0]); 132 133/* Extern Global Functions */ 134/******************************************************************************/ 135/* */ 136/* Function: cleanup */ 137/* */ 138/* Description: Performs all one time clean up for this test on successful */ 139/* completion, premature exit or failure. Closes all temporary */ 140/* files, removes all temporary directories exits the test with */ 141/* appropriate return code by calling tst_exit() function. */ 142/* */ 143/* Input: None. */ 144/* */ 145/* Output: None. */ 146/* */ 147/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */ 148/* On success - Exits calling tst_exit(). With '0' return code. */ 149/* */ 150/******************************************************************************/ 151extern void cleanup() 152{ 153 /* 154 * print timing stats if that option was specified. 155 * print errno log if that option was specified. 156 */ 157 TEST_CLEANUP; 158 159 /* close the file we have open */ 160 if (close(filed) == -1) { 161 tst_resm(TWARN|TERRNO, "close(%s) failed", filename); 162 } 163 164 tst_rmdir(); 165} 166 167/* Local Functions */ 168/******************************************************************************/ 169/* */ 170/* Function: setup */ 171/* */ 172/* Description: Performs all one time setup for this test. This function is */ 173/* typically used to capture signals, create temporary dirs */ 174/* and temporary files that may be used in the course of this */ 175/* test. */ 176/* */ 177/* Input: None. */ 178/* */ 179/* Output: None. */ 180/* */ 181/* Return: On failure - Exits by calling cleanup(). */ 182/* On success - returns 0. */ 183/* */ 184/******************************************************************************/ 185void setup() 186{ 187 188 tst_sig(NOFORK, DEF_HANDLER, cleanup); 189 190 TEST_PAUSE; 191 192 tst_tmpdir(); 193 194 sprintf(filename, "tmpfile_%d", getpid()); 195 if ((filed = open(filename, O_RDWR | O_CREAT, 0700)) == -1) { 196 tst_brkm(TBROK|TERRNO, cleanup, 197 "open(%s, O_RDWR|O_CREAT,0700) failed", filename); 198 } 199 200 sfd = open(spl_file, O_RDWR|O_CREAT, 0700); 201} 202 203/***************************************************************************** 204 * Wraper function to call sync_file_range system call 205 ******************************************************************************/ 206static inline long syncfilerange(int fd, off64_t offset, off64_t nbytes, 207 unsigned int flags) 208{ 209 210#if (defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__)) 211#if (__WORDSIZE == 32) 212#if __BYTE_ORDER == __BIG_ENDIAN 213 return syscall(__NR_sync_file_range2, fd, flags, (int)(offset >> 32), 214 (int)offset, (int)(nbytes >> 32), (int)nbytes); 215#elif __BYTE_ORDER == __LITTLE_ENDIAN 216 return syscall(__NR_sync_file_range2, fd, flags, (int)offset, 217 (int)(offset >> 32), nbytes, (int)(nbytes >> 32)); 218#endif 219#else 220 return syscall(__NR_sync_file_range2, fd, flags, offset, nbytes); 221#endif 222#else 223 return syscall(__NR_sync_file_range, fd, offset, nbytes, flags); 224#endif 225 226} 227 228/******************************************************************************/ 229/* */ 230/* Function: main */ 231/* */ 232/* Description: Entry point to this test-case. It parses all the command line */ 233/* inputs, calls the global setup and executes the test. It logs */ 234/* the test status and results appropriately using the LTP API's */ 235/* On successful completion or premature failure, cleanup() func */ 236/* is called and test exits with an appropriate return code. */ 237/* */ 238/* Input: Describe input arguments to this test-case */ 239/* -l - Number of iteration */ 240/* -v - Prints verbose output */ 241/* -V - Prints the version number */ 242/* */ 243/* Exit: On failure - Exits by calling cleanup(). */ 244/* On success - exits with 0 exit value. */ 245/* */ 246/******************************************************************************/ 247int main(int ac, char **av) 248{ 249 250 int test_index = 0; 251 char *msg; 252 253 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) 254 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 255 256#if defined(__powerpc__) || defined(__powerpc64__) /* for PPC, kernel version > 2.6.21 needed */ 257 if (tst_kvercmp(2, 16, 22) < 0) { 258 tst_brkm(TCONF, NULL, "System doesn't support execution of the test"); 259 } 260#else 261 /* For other archs, need kernel version > 2.6.16 */ 262 263 if (tst_kvercmp(2, 6, 17) < 0) { 264 tst_brkm(TCONF, NULL, "System doesn't support execution of the test"); 265 } 266#endif 267 268 setup(); 269 270 for (test_index = 0; test_index < TST_TOTAL; test_index++) { 271 TEST(syncfilerange 272 (*(test_data[test_index].fd), 273 test_data[test_index].offset, 274 test_data[test_index].nbytes, 275 test_data[test_index].flags)); 276 277 if (TEST_RETURN != -1) { 278 tst_resm(TFAIL, 279 "call succeeded unexpectedly (%ld != -1)", 280 TEST_RETURN); 281 continue; 282 } 283 284 TEST_ERROR_LOG(TEST_ERRNO); 285 286 if (TEST_ERRNO == test_data[test_index].error) { 287 tst_resm(TPASS|TTERRNO, "got expected error"); 288 } else { 289 tst_resm(TFAIL|TTERRNO, "got unexpected error; " 290 "expected %d", 291 test_data[test_index].error); 292 } 293 294 } 295 296 cleanup(); 297 tst_exit(); 298} 299