1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) Zilogic Systems Pvt. Ltd., 2018
4*49cdfc7eSAndroid Build Coastguard Worker * Email : [email protected]
5*49cdfc7eSAndroid Build Coastguard Worker */
6*49cdfc7eSAndroid Build Coastguard Worker
7*49cdfc7eSAndroid Build Coastguard Worker /*\
8*49cdfc7eSAndroid Build Coastguard Worker * [Description]
9*49cdfc7eSAndroid Build Coastguard Worker *
10*49cdfc7eSAndroid Build Coastguard Worker * This code tests the following flags:
11*49cdfc7eSAndroid Build Coastguard Worker *
12*49cdfc7eSAndroid Build Coastguard Worker * - AT_STATX_FORCE_SYNC
13*49cdfc7eSAndroid Build Coastguard Worker * - AT_STATX_DONT_SYNC
14*49cdfc7eSAndroid Build Coastguard Worker *
15*49cdfc7eSAndroid Build Coastguard Worker * By exportfs cmd creating NFS setup.
16*49cdfc7eSAndroid Build Coastguard Worker *
17*49cdfc7eSAndroid Build Coastguard Worker * A test file is created in server folder and statx is being
18*49cdfc7eSAndroid Build Coastguard Worker * done in client folder.
19*49cdfc7eSAndroid Build Coastguard Worker *
20*49cdfc7eSAndroid Build Coastguard Worker * BY AT_STATX_SYNC_AS_STAT getting predefined mode value.
21*49cdfc7eSAndroid Build Coastguard Worker * Then, by using AT_STATX_FORCE_SYNC getting new updated vaue
22*49cdfc7eSAndroid Build Coastguard Worker * from server file changes.
23*49cdfc7eSAndroid Build Coastguard Worker *
24*49cdfc7eSAndroid Build Coastguard Worker * BY AT_STATX_SYNC_AS_STAT getting predefined mode value.
25*49cdfc7eSAndroid Build Coastguard Worker * AT_STATX_FORCE_SYNC is called to create cache data of the file.
26*49cdfc7eSAndroid Build Coastguard Worker * Then, by using DONT_SYNC_FILE getting old cached data in client folder,
27*49cdfc7eSAndroid Build Coastguard Worker * but mode has been chaged in server file.
28*49cdfc7eSAndroid Build Coastguard Worker *
29*49cdfc7eSAndroid Build Coastguard Worker * The support for SYNC flags was implemented in NFS in:
30*49cdfc7eSAndroid Build Coastguard Worker * 9ccee940bd5b ("Support statx() mask and query flags parameters")
31*49cdfc7eSAndroid Build Coastguard Worker */
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
34*49cdfc7eSAndroid Build Coastguard Worker #include <netdb.h>
35*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
36*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
37*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
38*49cdfc7eSAndroid Build Coastguard Worker #include <linux/limits.h>
39*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mount.h>
40*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
41*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/stat.h"
42*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/fcntl.h"
43*49cdfc7eSAndroid Build Coastguard Worker
44*49cdfc7eSAndroid Build Coastguard Worker #define MODE(X) (X & (~S_IFMT))
45*49cdfc7eSAndroid Build Coastguard Worker #define FLAG_NAME(x) .flag = x, .flag_name = #x
46*49cdfc7eSAndroid Build Coastguard Worker #define BUFF_SIZE PATH_MAX
47*49cdfc7eSAndroid Build Coastguard Worker #define DEFAULT_MODE 0644
48*49cdfc7eSAndroid Build Coastguard Worker #define CURRENT_MODE 0777
49*49cdfc7eSAndroid Build Coastguard Worker
50*49cdfc7eSAndroid Build Coastguard Worker #define CLI_PATH "client"
51*49cdfc7eSAndroid Build Coastguard Worker #define SERV_PATH "server"
52*49cdfc7eSAndroid Build Coastguard Worker #define CLI_FORCE_SYNC "client/force_sync_file"
53*49cdfc7eSAndroid Build Coastguard Worker #define CLI_DONT_SYNC "client/dont_sync_file"
54*49cdfc7eSAndroid Build Coastguard Worker #define SERV_FORCE_SYNC "server/force_sync_file"
55*49cdfc7eSAndroid Build Coastguard Worker #define SERV_DONT_SYNC "server/dont_sync_file"
56*49cdfc7eSAndroid Build Coastguard Worker
57*49cdfc7eSAndroid Build Coastguard Worker static char *cwd;
58*49cdfc7eSAndroid Build Coastguard Worker static char cmd[BUFF_SIZE];
59*49cdfc7eSAndroid Build Coastguard Worker static int mounted;
60*49cdfc7eSAndroid Build Coastguard Worker static int exported;
61*49cdfc7eSAndroid Build Coastguard Worker
get_mode(char * file_name,int flag_type,char * flag_name)62*49cdfc7eSAndroid Build Coastguard Worker static int get_mode(char *file_name, int flag_type, char *flag_name)
63*49cdfc7eSAndroid Build Coastguard Worker {
64*49cdfc7eSAndroid Build Coastguard Worker struct statx buf;
65*49cdfc7eSAndroid Build Coastguard Worker
66*49cdfc7eSAndroid Build Coastguard Worker TEST(statx(AT_FDCWD, file_name, flag_type, STATX_BASIC_STATS, &buf));
67*49cdfc7eSAndroid Build Coastguard Worker
68*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
69*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TFAIL | TST_ERR,
70*49cdfc7eSAndroid Build Coastguard Worker "statx(AT_FDCWD, %s, %s, STATX_BASIC_STATS, &buf)",
71*49cdfc7eSAndroid Build Coastguard Worker file_name, flag_name);
72*49cdfc7eSAndroid Build Coastguard Worker }
73*49cdfc7eSAndroid Build Coastguard Worker
74*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "statx(AT_FDCWD, %s, %s, STATX_BASIC_STATS, &buf) = %o",
75*49cdfc7eSAndroid Build Coastguard Worker file_name, flag_name, buf.stx_mode);
76*49cdfc7eSAndroid Build Coastguard Worker
77*49cdfc7eSAndroid Build Coastguard Worker return buf.stx_mode;
78*49cdfc7eSAndroid Build Coastguard Worker }
79*49cdfc7eSAndroid Build Coastguard Worker
80*49cdfc7eSAndroid Build Coastguard Worker static const struct test_cases {
81*49cdfc7eSAndroid Build Coastguard Worker int flag;
82*49cdfc7eSAndroid Build Coastguard Worker char *flag_name;
83*49cdfc7eSAndroid Build Coastguard Worker char *server_file;
84*49cdfc7eSAndroid Build Coastguard Worker char *client_file;
85*49cdfc7eSAndroid Build Coastguard Worker unsigned int mode;
86*49cdfc7eSAndroid Build Coastguard Worker } tcases[] = {
87*49cdfc7eSAndroid Build Coastguard Worker {FLAG_NAME(AT_STATX_DONT_SYNC), SERV_DONT_SYNC, CLI_DONT_SYNC, DEFAULT_MODE},
88*49cdfc7eSAndroid Build Coastguard Worker {FLAG_NAME(AT_STATX_FORCE_SYNC), SERV_FORCE_SYNC, CLI_FORCE_SYNC, CURRENT_MODE}
89*49cdfc7eSAndroid Build Coastguard Worker };
90*49cdfc7eSAndroid Build Coastguard Worker
test_statx(unsigned int i)91*49cdfc7eSAndroid Build Coastguard Worker static void test_statx(unsigned int i)
92*49cdfc7eSAndroid Build Coastguard Worker {
93*49cdfc7eSAndroid Build Coastguard Worker const struct test_cases *tc = &tcases[i];
94*49cdfc7eSAndroid Build Coastguard Worker unsigned int cur_mode;
95*49cdfc7eSAndroid Build Coastguard Worker
96*49cdfc7eSAndroid Build Coastguard Worker get_mode(tc->client_file, AT_STATX_FORCE_SYNC, "AT_STATX_FORCE_SYNC");
97*49cdfc7eSAndroid Build Coastguard Worker
98*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHMOD(tc->server_file, CURRENT_MODE);
99*49cdfc7eSAndroid Build Coastguard Worker cur_mode = get_mode(tc->client_file, tc->flag, tc->flag_name);
100*49cdfc7eSAndroid Build Coastguard Worker
101*49cdfc7eSAndroid Build Coastguard Worker if (MODE(cur_mode) == tc->mode) {
102*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS,
103*49cdfc7eSAndroid Build Coastguard Worker "statx() with %s for mode %o",
104*49cdfc7eSAndroid Build Coastguard Worker tc->flag_name, tc->mode);
105*49cdfc7eSAndroid Build Coastguard Worker } else {
106*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL,
107*49cdfc7eSAndroid Build Coastguard Worker "statx() with %s for mode %o %o",
108*49cdfc7eSAndroid Build Coastguard Worker tc->flag_name, tc->mode, MODE(cur_mode));
109*49cdfc7eSAndroid Build Coastguard Worker }
110*49cdfc7eSAndroid Build Coastguard Worker
111*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHMOD(tc->server_file, DEFAULT_MODE);
112*49cdfc7eSAndroid Build Coastguard Worker }
113*49cdfc7eSAndroid Build Coastguard Worker
setup(void)114*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
115*49cdfc7eSAndroid Build Coastguard Worker {
116*49cdfc7eSAndroid Build Coastguard Worker int ret;
117*49cdfc7eSAndroid Build Coastguard Worker char server_path[BUFF_SIZE];
118*49cdfc7eSAndroid Build Coastguard Worker
119*49cdfc7eSAndroid Build Coastguard Worker cwd = tst_get_tmpdir();
120*49cdfc7eSAndroid Build Coastguard Worker
121*49cdfc7eSAndroid Build Coastguard Worker mode_t old_umask = umask(0);
122*49cdfc7eSAndroid Build Coastguard Worker
123*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(SERV_PATH, DEFAULT_MODE);
124*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(CLI_PATH, DEFAULT_MODE);
125*49cdfc7eSAndroid Build Coastguard Worker SAFE_CREAT(SERV_FORCE_SYNC, DEFAULT_MODE);
126*49cdfc7eSAndroid Build Coastguard Worker SAFE_CREAT(SERV_DONT_SYNC, DEFAULT_MODE);
127*49cdfc7eSAndroid Build Coastguard Worker
128*49cdfc7eSAndroid Build Coastguard Worker umask(old_umask);
129*49cdfc7eSAndroid Build Coastguard Worker
130*49cdfc7eSAndroid Build Coastguard Worker snprintf(server_path, sizeof(server_path), ":%s/%s", cwd, SERV_PATH);
131*49cdfc7eSAndroid Build Coastguard Worker
132*49cdfc7eSAndroid Build Coastguard Worker snprintf(cmd, sizeof(cmd),
133*49cdfc7eSAndroid Build Coastguard Worker "exportfs -i -o no_root_squash,rw,sync,no_subtree_check,fsid=%d *%.1024s",
134*49cdfc7eSAndroid Build Coastguard Worker getpid(), server_path);
135*49cdfc7eSAndroid Build Coastguard Worker exported = 1;
136*49cdfc7eSAndroid Build Coastguard Worker
137*49cdfc7eSAndroid Build Coastguard Worker ret = tst_system(cmd);
138*49cdfc7eSAndroid Build Coastguard Worker if (ret)
139*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TST_ERR, "failed to exportfs");
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker if (mount(server_path, CLI_PATH, "nfs", 0, "addr=127.0.0.1")) {
142*49cdfc7eSAndroid Build Coastguard Worker if (errno == EOPNOTSUPP || errno == ECONNREFUSED
143*49cdfc7eSAndroid Build Coastguard Worker || errno == ETIMEDOUT)
144*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF | TERRNO, "nfs server not set up?");
145*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "mount() nfs failed");
146*49cdfc7eSAndroid Build Coastguard Worker }
147*49cdfc7eSAndroid Build Coastguard Worker mounted = 1;
148*49cdfc7eSAndroid Build Coastguard Worker }
149*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)150*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
151*49cdfc7eSAndroid Build Coastguard Worker {
152*49cdfc7eSAndroid Build Coastguard Worker if (mounted)
153*49cdfc7eSAndroid Build Coastguard Worker SAFE_UMOUNT(CLI_PATH);
154*49cdfc7eSAndroid Build Coastguard Worker
155*49cdfc7eSAndroid Build Coastguard Worker if (!exported)
156*49cdfc7eSAndroid Build Coastguard Worker return;
157*49cdfc7eSAndroid Build Coastguard Worker snprintf(cmd, sizeof(cmd),
158*49cdfc7eSAndroid Build Coastguard Worker "exportfs -u *:%s/%s", cwd, SERV_PATH);
159*49cdfc7eSAndroid Build Coastguard Worker
160*49cdfc7eSAndroid Build Coastguard Worker if (tst_system(cmd) == -1)
161*49cdfc7eSAndroid Build Coastguard Worker tst_res(TWARN | TST_ERR, "failed to clear exportfs");
162*49cdfc7eSAndroid Build Coastguard Worker }
163*49cdfc7eSAndroid Build Coastguard Worker
164*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
165*49cdfc7eSAndroid Build Coastguard Worker .tcnt = ARRAY_SIZE(tcases),
166*49cdfc7eSAndroid Build Coastguard Worker .test = test_statx,
167*49cdfc7eSAndroid Build Coastguard Worker .setup = setup,
168*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup,
169*49cdfc7eSAndroid Build Coastguard Worker .min_kver = "4.16",
170*49cdfc7eSAndroid Build Coastguard Worker .needs_tmpdir = 1,
171*49cdfc7eSAndroid Build Coastguard Worker .dev_fs_type = "nfs",
172*49cdfc7eSAndroid Build Coastguard Worker .needs_root = 1,
173*49cdfc7eSAndroid Build Coastguard Worker .needs_cmds = (const char *[]) {
174*49cdfc7eSAndroid Build Coastguard Worker "exportfs",
175*49cdfc7eSAndroid Build Coastguard Worker NULL
176*49cdfc7eSAndroid Build Coastguard Worker }
177*49cdfc7eSAndroid Build Coastguard Worker };
178