xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/sync_file_range/sync_file_range01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines  Corp., 2008
4  * Email: [email protected]
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Basic error conditions test for sync_file_range() system call, tests for:
11  *
12  * - EBADFD Wrong filedescriptor
13  * - ESPIPE Unsupported file descriptor
14  * - EINVAL Wrong offset
15  * - EINVAL Wrong nbytes
16  * - EINVAL Wrong flags
17  */
18 #define _GNU_SOURCE
19 
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/utsname.h>
23 #include <endian.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
28 #include "tst_test.h"
29 #include "lapi/sync_file_range.h"
30 #include "check_sync_file_range.h"
31 
32 #ifndef SYNC_FILE_RANGE_WAIT_BEFORE
33 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
34 #define SYNC_FILE_RANGE_WRITE 2
35 #define SYNC_FILE_RANGE_WAIT_AFTER 4
36 #endif
37 
38 #define SYNC_FILE_RANGE_INVALID 8
39 
40 static char filename[255];
41 static const char spl_file[] = "/dev/null";
42 static int fd, sfd;
43 static int bfd = -1;
44 
45 struct test_case {
46 	int *fd;
47 	off_t offset;
48 	off_t nbytes;
49 	unsigned int flags;
50 	int error;
51 } tcases[] = {
52 	{&bfd, 0, 1, SYNC_FILE_RANGE_WRITE, EBADF},
53 	{&sfd, 0, 1, SYNC_FILE_RANGE_WAIT_AFTER, ESPIPE},
54 	{&fd, -1, 1, SYNC_FILE_RANGE_WAIT_BEFORE, EINVAL},
55 	{&fd, 0, -1, SYNC_FILE_RANGE_WRITE, EINVAL},
56 	{&fd, 0, 1, SYNC_FILE_RANGE_INVALID, EINVAL}
57 };
58 
cleanup(void)59 static void cleanup(void)
60 {
61 	SAFE_CLOSE(fd);
62 }
63 
setup(void)64 static void setup(void)
65 {
66 	if (!check_sync_file_range())
67 		tst_brk(TCONF, "sync_file_range() not supported");
68 
69 	sprintf(filename, "tmpfile_%d", getpid());
70 
71 	fd = SAFE_OPEN(filename, O_RDWR | O_CREAT, 0700);
72 	sfd = SAFE_OPEN(spl_file, O_RDWR | O_CREAT, 0700);
73 }
74 
run_test(unsigned int nr)75 static void run_test(unsigned int nr)
76 {
77 	struct test_case *tc = &tcases[nr];
78 
79 	TST_EXP_FAIL(tst_syscall(__NR_sync_file_range, *(tc->fd),
80 		tc->offset, tc->nbytes, tc->flags), tc->error,
81 		"sync_file_range(%i, %li, %li, %i)",
82 		*(tc->fd), (long)tc->offset, (long)tc->nbytes, tc->flags);
83 }
84 
85 static struct tst_test test = {
86 	.setup = setup,
87 	.tcnt = ARRAY_SIZE(tcases),
88 	.test = run_test,
89 	.cleanup = cleanup,
90 	.needs_tmpdir = 1,
91 };
92