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