1 /*
2 * Copyright (c) 2015-2016 Cyril Hrubis <chrubis@suse.cz>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef TST_FS_H__
19 #define TST_FS_H__
20
21 /* man 2 statfs or kernel-source/include/linux/magic.h */
22 #define TST_BTRFS_MAGIC 0x9123683E
23 #define TST_NFS_MAGIC 0x6969
24 #define TST_RAMFS_MAGIC 0x858458f6
25 #define TST_TMPFS_MAGIC 0x01021994
26 #define TST_V9FS_MAGIC 0x01021997
27 #define TST_XFS_MAGIC 0x58465342
28 #define TST_EXT2_OLD_MAGIC 0xEF51
29 /* ext2, ext3, ext4 have the same magic number */
30 #define TST_EXT234_MAGIC 0xEF53
31 #define TST_MINIX_MAGIC 0x137F
32 #define TST_MINIX_MAGIC2 0x138F
33 #define TST_MINIX2_MAGIC 0x2468
34 #define TST_MINIX2_MAGIC2 0x2478
35 #define TST_MINIX3_MAGIC 0x4D5A
36 #define TST_UDF_MAGIC 0x15013346
37 #define TST_SYSV2_MAGIC 0x012FF7B6
38 #define TST_SYSV4_MAGIC 0x012FF7B5
39 #define TST_UFS_MAGIC 0x00011954
40 #define TST_UFS2_MAGIC 0x19540119
41 #define TST_F2FS_MAGIC 0xF2F52010
42 #define TST_NILFS_MAGIC 0x3434
43 #define TST_EXOFS_MAGIC 0x5DF5
44 #define TST_OVERLAYFS_MAGIC 0x794c7630
45
46 enum {
47 TST_BYTES = 1,
48 TST_KB = 1024,
49 TST_MB = 1048576,
50 TST_GB = 1073741824,
51 };
52
53 #define OVL_BASE_MNTPOINT "mntpoint"
54 #define OVL_LOWER OVL_BASE_MNTPOINT"/lower"
55 #define OVL_UPPER OVL_BASE_MNTPOINT"/upper"
56 #define OVL_WORK OVL_BASE_MNTPOINT"/work"
57 #define OVL_MNT OVL_BASE_MNTPOINT"/ovl"
58
59 /*
60 * @path: path is the pathname of any file within the mounted file system
61 * @mult: mult should be TST_KB, TST_MB or TST_GB
62 * the required free space is calculated by @size * @mult
63 */
64 int tst_fs_has_free_(void (*cleanup)(void), const char *path,
65 unsigned int size, unsigned int mult);
66
67 /*
68 * Returns filesystem magick for a given path.
69 *
70 * The expected usage is:
71 *
72 * if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
73 * tst_brkm(TCONF, cleanup,
74 * "Test not supported on NFS filesystem");
75 * }
76 *
77 * Or:
78 *
79 * long type;
80 *
81 * swtich ((type = tst_fs_type(cleanup, "."))) {
82 * case TST_NFS_MAGIC:
83 * case TST_TMPFS_MAGIC:
84 * case TST_RAMFS_MAGIC:
85 * tst_brkm(TCONF, cleanup, "Test not supported on %s filesystem",
86 * tst_fs_type_name(type));
87 * break;
88 * }
89 */
90 long tst_fs_type_(void (*cleanup)(void), const char *path);
91
92 /*
93 * Returns filesystem name given magic.
94 */
95 const char *tst_fs_type_name(long f_type);
96
97 /*
98 * Try to get maximum number of hard links to a regular file inside the @dir.
99 *
100 * Note: This number depends on the filesystem @dir is on.
101 *
102 * The code uses link(2) to create hard links to a single file until it gets
103 * EMLINK or creates 65535 links.
104 *
105 * If limit is hit maximal number of hardlinks is returned and the the @dir is
106 * filled with hardlinks in format "testfile%i" where i belongs to [0, limit)
107 * interval.
108 *
109 * If no limit is hit (succed to create 65535 without error) or if link()
110 * failed with ENOSPC or EDQUOT zero is returned previously created files are
111 * removed.
112 */
113 int tst_fs_fill_hardlinks_(void (*cleanup) (void), const char *dir);
114
115 /*
116 * Try to get maximum number of subdirectories in directory.
117 *
118 * Note: This number depends on the filesystem @dir is on.
119 *
120 * The code uses mkdir(2) to create directories in @dir until it gets EMLINK
121 * or creates 65535 directories.
122 *
123 * If limit is hit the maximal number of subdirectories is returned and the
124 * @dir is filled with subdirectories in format "testdir%i" where i belongs to
125 * [0, limit - 2) interval (because each newly created dir has two links
126 * already the '.' and link from parent dir).
127 *
128 * If no limit is hit or mkdir() failed with ENOSPC or EDQUOT zero is returned
129 * previously created directories are removed.
130 *
131 */
132 int tst_fs_fill_subdirs_(void (*cleanup) (void), const char *dir);
133
134 /*
135 * Checks if a given directory contains any entities,
136 * returns 1 if directory is empty, 0 otherwise
137 */
138 int tst_dir_is_empty_(void (*cleanup)(void), const char *name, int verbose);
139
140 /*
141 * Search $PATH for prog_name and fills buf with absolute path if found.
142 *
143 * Returns -1 on failure, either command was not found or buffer was too small.
144 */
145 int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
146
147 /*
148 * Fill a file with specified pattern
149 * @fd: file descriptor
150 * @pattern: pattern
151 * @bs: block size
152 * @bcount: blocks count
153 */
154 int tst_fill_fd(int fd, char pattern, size_t bs, size_t bcount);
155
156 /*
157 * Creates/ovewrites a file with specified pattern
158 * @path: path to file
159 * @pattern: pattern
160 * @bs: block size
161 * @bcount: blocks amount
162 */
163 int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
164
165 #define TST_FS_SKIP_FUSE 0x01
166
167 /*
168 * Return 1 if a specified fiilsystem is supported
169 * Return 0 if a specified fiilsystem isn't supported
170 */
171 int tst_fs_is_supported(const char *fs_type, int flags);
172
173 /*
174 * Returns NULL-terminated array of kernel-supported filesystems.
175 */
176 const char **tst_get_supported_fs_types(int flags);
177
178 /*
179 * Creates and writes to files on given path until write fails with ENOSPC
180 */
181 void tst_fill_fs(const char *path, int verbose);
182
183 /*
184 * test if FIBMAP ioctl is supported
185 */
186 int tst_fibmap(const char *filename);
187
188 #ifdef TST_TEST_H__
tst_fs_type(const char * path)189 static inline long tst_fs_type(const char *path)
190 {
191 return tst_fs_type_(NULL, path);
192 }
193
tst_fs_has_free(const char * path,unsigned int size,unsigned int mult)194 static inline int tst_fs_has_free(const char *path, unsigned int size,
195 unsigned int mult)
196 {
197 return tst_fs_has_free_(NULL, path, size, mult);
198 }
199
tst_fs_fill_hardlinks(const char * dir)200 static inline int tst_fs_fill_hardlinks(const char *dir)
201 {
202 return tst_fs_fill_hardlinks_(NULL, dir);
203 }
204
tst_fs_fill_subdirs(const char * dir)205 static inline int tst_fs_fill_subdirs(const char *dir)
206 {
207 return tst_fs_fill_subdirs_(NULL, dir);
208 }
209
tst_dir_is_empty(const char * name,int verbose)210 static inline int tst_dir_is_empty(const char *name, int verbose)
211 {
212 return tst_dir_is_empty_(NULL, name, verbose);
213 }
214 #else
tst_fs_type(void (* cleanup)(void),const char * path)215 static inline long tst_fs_type(void (*cleanup)(void), const char *path)
216 {
217 return tst_fs_type_(cleanup, path);
218 }
219
tst_fs_has_free(void (* cleanup)(void),const char * path,unsigned int size,unsigned int mult)220 static inline int tst_fs_has_free(void (*cleanup)(void), const char *path,
221 unsigned int size, unsigned int mult)
222 {
223 return tst_fs_has_free_(cleanup, path, size, mult);
224 }
225
tst_fs_fill_hardlinks(void (* cleanup)(void),const char * dir)226 static inline int tst_fs_fill_hardlinks(void (*cleanup)(void), const char *dir)
227 {
228 return tst_fs_fill_hardlinks_(cleanup, dir);
229 }
230
tst_fs_fill_subdirs(void (* cleanup)(void),const char * dir)231 static inline int tst_fs_fill_subdirs(void (*cleanup)(void), const char *dir)
232 {
233 return tst_fs_fill_subdirs_(cleanup, dir);
234 }
235
tst_dir_is_empty(void (* cleanup)(void),const char * name,int verbose)236 static inline int tst_dir_is_empty(void (*cleanup)(void), const char *name, int verbose)
237 {
238 return tst_dir_is_empty_(cleanup, name, verbose);
239 }
240 #endif
241
242 #endif /* TST_FS_H__ */
243