Home | History | Annotate | Download | only in sync_file_range
      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 "linux_syscall_numbers.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 	return ltp_syscall(__NR_sync_file_range, fd, 0, (int)(offset >> 32),
    222 		(int)offset, (int)(nbytes >> 32), (int)nbytes, flags);
    223 
    224 /* other */
    225 #else
    226 	return ltp_syscall(__NR_sync_file_range, fd, offset, nbytes, flags);
    227 #endif
    228 }
    229 
    230 /******************************************************************************/
    231 /*									    */
    232 /* Function:    main							  */
    233 /*									    */
    234 /* Description: Entry point to this test-case. It parses all the command line */
    235 /*	      inputs, calls the global setup and executes the test. It logs */
    236 /*	      the test status and results appropriately using the LTP API's */
    237 /*	      On successful completion or premature failure, cleanup() func */
    238 /*	      is called and test exits with an appropriate return code.     */
    239 /*									    */
    240 /* Input:       Describe input arguments to this test-case		    */
    241 /*	       -l - Number of iteration				     */
    242 /*	       -v - Prints verbose output				   */
    243 /*	       -V - Prints the version number			       */
    244 /*									    */
    245 /* Exit:       On failure - Exits by calling cleanup().		       */
    246 /*	     On success - exits with 0 exit value.			  */
    247 /*									    */
    248 /******************************************************************************/
    249 int main(int ac, char **av)
    250 {
    251 
    252 	int test_index = 0;
    253 
    254 	tst_parse_opts(ac, av, NULL, NULL);
    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,
    259 			 "System doesn't support execution of the test");
    260 	}
    261 #else
    262 	/* For other archs, need kernel version > 2.6.16 */
    263 
    264 	if (tst_kvercmp(2, 6, 17) < 0) {
    265 		tst_brkm(TCONF, NULL,
    266 			 "System doesn't support execution of the test");
    267 	}
    268 #endif
    269 
    270 	setup();
    271 
    272 	for (test_index = 0; test_index < TST_TOTAL; test_index++) {
    273 		TEST(syncfilerange
    274 		     (*(test_data[test_index].fd),
    275 		      test_data[test_index].offset,
    276 		      test_data[test_index].nbytes,
    277 		      test_data[test_index].flags));
    278 
    279 		if (TEST_RETURN != -1) {
    280 			tst_resm(TFAIL,
    281 				 "call succeeded unexpectedly (%ld != -1)",
    282 				 TEST_RETURN);
    283 			continue;
    284 		}
    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", test_data[test_index].error);
    291 		}
    292 
    293 	}
    294 
    295 	cleanup();
    296 	tst_exit();
    297 }
    298