1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
4 */
5
6 /*\
7 * [Description]
8 *
9 * This test verifies that cachestat() syscall is properly failing with relative
10 * error codes according to input parameters.
11 *
12 * - EFAULT: cstat or cstat_range points to an illegal address
13 * - EINVAL: invalid flags
14 * - EBADF: invalid file descriptor
15 * - EOPNOTSUPP: file descriptor is of a hugetlbfs file
16 */
17
18 #define MNTPOINT "mnt"
19
20 #include "cachestat.h"
21
22 static int fd;
23 static int fd_hugepage;
24 static int invalid_fd = -1;
25 static struct cachestat *cs;
26 static struct cachestat *cs_null;
27 static struct cachestat_range *cs_range;
28 static struct cachestat_range *cs_range_null;
29
30 static struct tcase {
31 int *fd;
32 struct cachestat_range **range;
33 struct cachestat **data;
34 int flags;
35 int exp_errno;
36 char *msg;
37 } tcases[] = {
38 {&invalid_fd, &cs_range, &cs, 0, EBADF, "Invalid fd (-1)"},
39 {&fd, &cs_range_null, &cs, 0, EFAULT, "Invalid range (NULL)"},
40 {&fd, &cs_range, &cs_null, 0, EFAULT, "Invalid data (NULL)"},
41 {&fd, &cs_range, &cs, -1, EINVAL, "Invalid args (-1)"},
42 {&fd_hugepage, &cs_range, &cs, 0, EOPNOTSUPP, "Unsupported hugetlbfs"},
43 };
44
run(unsigned int i)45 static void run(unsigned int i)
46 {
47 struct tcase *tc = &tcases[i];
48
49 TST_EXP_FAIL(cachestat(*tc->fd, *tc->range, *tc->data, tc->flags),
50 tc->exp_errno, "%s", tc->msg);
51 }
52
setup(void)53 static void setup(void)
54 {
55 fd = SAFE_OPEN("test", O_CREAT | O_RDWR, 0700);
56 fd_hugepage = SAFE_OPEN(MNTPOINT"/test", O_CREAT | O_RDWR, 0700);
57 }
58
cleanup(void)59 static void cleanup(void)
60 {
61 SAFE_CLOSE(fd);
62 SAFE_CLOSE(fd_hugepage);
63 }
64
65 static struct tst_test test = {
66 .test = run,
67 .setup = setup,
68 .cleanup = cleanup,
69 .mntpoint = MNTPOINT,
70 .needs_hugetlbfs = 1,
71 .hugepages = {1, TST_NEEDS},
72 .tcnt = ARRAY_SIZE(tcases),
73 .needs_tmpdir = 1,
74 .bufs = (struct tst_buffers []) {
75 {&cs, .size = sizeof(struct cachestat)},
76 {&cs_range, .size = sizeof(struct cachestat_range)},
77 {}
78 },
79 };
80