• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright (c) 2015-2017 Cyril Hrubis <chrubis@suse.cz>
3  * Copyright (c) Linux Test Project, 2017-2022
4  */
5 
6 #ifndef TST_FS_H__
7 #define TST_FS_H__
8 
9 /* man 2 statfs or kernel-source/include/uapi/linux/magic.h */
10 #define TST_BTRFS_MAGIC    0x9123683E
11 #define TST_NFS_MAGIC      0x6969
12 #define TST_RAMFS_MAGIC    0x858458f6
13 #define TST_TMPFS_MAGIC    0x01021994
14 #define TST_V9FS_MAGIC     0x01021997
15 #define TST_XFS_MAGIC      0x58465342
16 #define TST_EXT2_OLD_MAGIC 0xEF51
17 /* ext2, ext3, ext4 have the same magic number */
18 #define TST_EXT234_MAGIC   0xEF53
19 #define TST_MINIX_MAGIC    0x137F
20 #define TST_MINIX_MAGIC2   0x138F
21 #define TST_MINIX2_MAGIC   0x2468
22 #define TST_MINIX2_MAGIC2  0x2478
23 #define TST_MINIX3_MAGIC   0x4D5A
24 #define TST_UDF_MAGIC      0x15013346
25 #define TST_SYSV2_MAGIC    0x012FF7B6
26 #define TST_SYSV4_MAGIC    0x012FF7B5
27 #define TST_UFS_MAGIC      0x00011954
28 #define TST_UFS2_MAGIC     0x19540119
29 #define TST_F2FS_MAGIC     0xF2F52010
30 #define TST_NILFS_MAGIC    0x3434
31 #define TST_EXOFS_MAGIC    0x5DF5
32 #define TST_OVERLAYFS_MAGIC 0x794c7630
33 #define TST_FUSE_MAGIC     0x65735546
34 #define TST_VFAT_MAGIC     0x4d44 /* AKA MSDOS */
35 #define TST_EXFAT_MAGIC    0x2011BAB0UL
36 
37 /* fs/bcachefs/bcachefs_format.h */
38 #define TST_BCACHE_MAGIC		0xca451a4e
39 
40 enum tst_fill_access_pattern {
41 	TST_FILL_BLOCKS,
42 	TST_FILL_RANDOM
43 };
44 
45 enum {
46 	TST_BYTES = 1,
47 	TST_KB = 1024,
48 	TST_MB = 1048576,
49 	TST_GB = 1073741824,
50 };
51 
52 #define OVL_BASE_MNTPOINT        "mntpoint"
53 #define OVL_LOWER	OVL_BASE_MNTPOINT"/lower"
54 #define OVL_UPPER	OVL_BASE_MNTPOINT"/upper"
55 #define OVL_WORK	OVL_BASE_MNTPOINT"/work"
56 #define OVL_MNT		OVL_BASE_MNTPOINT"/ovl"
57 
58 /*
59  * @path: path is the pathname of any file within the mounted file system
60  * @mult: mult should be TST_KB, TST_MB or TST_GB
61  * the required free space is calculated by @size * @mult
62  */
63 int tst_fs_has_free_(void (*cleanup)(void), const char *path, unsigned int size,
64 		     unsigned int mult);
65 
66 /*
67  * Returns filesystem magick for a given path.
68  *
69  * The expected usage is:
70  *
71  *      if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
72  *		tst_brkm(TCONF, cleanup,
73  *		         "Test not supported on NFS filesystem");
74  *	}
75  *
76  * Or:
77  *
78  *	long type;
79  *
80  *	swtich ((type = tst_fs_type(cleanup, "."))) {
81  *	case TST_NFS_MAGIC:
82  *	case TST_TMPFS_MAGIC:
83  *	case TST_RAMFS_MAGIC:
84  *		tst_brkm(TCONF, cleanup, "Test not supported on %s filesystem",
85  *		         tst_fs_type_name(type));
86  *	break;
87  *	}
88  */
89 long tst_fs_type_(void (*cleanup)(void), const char *path);
90 
91 /*
92  * Returns filesystem name given magic.
93  */
94 const char *tst_fs_type_name(long f_type);
95 
96 /*
97  * Try to get maximum number of hard links to a regular file inside the @dir.
98  *
99  * Note: This number depends on the filesystem @dir is on.
100  *
101  * The code uses link(2) to create hard links to a single file until it gets
102  * EMLINK or creates 65535 links.
103  *
104  * If limit is hit maximal number of hardlinks is returned and the @dir is
105  * filled with hardlinks in format "testfile%i" where i belongs to [0, limit)
106  * interval.
107  *
108  * If no limit is hit (succed to create 65535 without error) or if link()
109  * failed with ENOSPC or EDQUOT zero is returned previously created files are
110  * removed.
111  */
112 int tst_fs_fill_hardlinks_(void (*cleanup) (void), const char *dir);
113 
114 /*
115  * Try to get maximum number of subdirectories in directory.
116  *
117  * Note: This number depends on the filesystem @dir is on.
118  *
119  * The code uses mkdir(2) to create directories in @dir until it gets EMLINK
120  * or creates 65535 directories.
121  *
122  * If limit is hit the maximal number of subdirectories is returned and the
123  * @dir is filled with subdirectories in format "testdir%i" where i belongs to
124  * [0, limit - 2) interval (because each newly created dir has two links
125  * already the '.' and link from parent dir).
126  *
127  * If no limit is hit or mkdir() failed with ENOSPC or EDQUOT zero is returned
128  * previously created directories are removed.
129  *
130  */
131 int tst_fs_fill_subdirs_(void (*cleanup) (void), const char *dir);
132 
133 /*
134  * Checks if a given directory contains any entities,
135  * returns 1 if directory is empty, 0 otherwise
136  */
137 int tst_dir_is_empty_(void (*cleanup)(void), const char *name, int verbose);
138 
139 /*
140  * Search $PATH for prog_name and fills buf with absolute path if found.
141  *
142  * Returns -1 on failure, either command was not found or buffer was too small.
143  */
144 int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
145 
146 /*
147  * Fill a file with specified pattern
148  * @fd: file descriptor
149  * @pattern: pattern
150  * @bs: block size
151  * @bcount: blocks count
152  */
153 int tst_fill_fd(int fd, char pattern, size_t bs, size_t bcount);
154 
155 /*
156  * Preallocate space in open file. If fallocate() fails, falls back to
157  * using tst_fill_fd().
158  * @fd: file descriptor
159  * @bs: block size
160  * @bcount: blocks count
161  */
162 int tst_prealloc_size_fd(int fd, size_t bs, size_t bcount);
163 
164 /*
165  * Creates/ovewrites a file with specified pattern
166  * @path: path to file
167  * @pattern: pattern
168  * @bs: block size
169  * @bcount: blocks amount
170  */
171 int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
172 
173 /*
174  * Creates file of specified size. Space will be only preallocated if possible.
175  * @path: path to file
176  * @bs: block size
177  * @bcount: blocks amount
178  */
179 int tst_prealloc_file(const char *path, size_t bs, size_t bcount);
180 
181 enum tst_fs_impl {
182 	TST_FS_UNSUPPORTED = 0,
183 	TST_FS_KERNEL = 1,
184 	TST_FS_FUSE = 2,
185 };
186 
187 /*
188  * Returns if filesystem is supported and if driver is in kernel or FUSE.
189  *
190  * @fs_type A filesystem name to check the support for.
191  */
192 enum tst_fs_impl tst_fs_is_supported(const char *fs_type);
193 
194 /*
195  * Returns NULL-terminated array of kernel-supported filesystems.
196  *
197  * @skiplist A NULL terminated array of filesystems to skip.
198  */
199 const char **tst_get_supported_fs_types(const char *const *skiplist);
200 
201 /*
202  * Returns 1 if filesystem is in skiplist 0 otherwise.
203  *
204  * @fs_type A filesystem type to lookup.
205  * @skiplist A NULL terminated array of filesystems to skip.
206  */
207 int tst_fs_in_skiplist(const char *fs_type, const char *const *skiplist);
208 
209 /*
210  * Creates and writes to files on given path until write fails with ENOSPC
211  */
212 void tst_fill_fs(const char *path, int verbose, enum tst_fill_access_pattern pattern);
213 
214 /*
215  * Check if FIBMAP ioctl is supported.
216  * Tests needs to set .needs_root = 1 in order to avoid EPERM.
217  *
218  * @return 0: FIBMAP is supported, 1: FIBMAP is *not* supported.
219  */
220 int tst_fibmap(const char *filename);
221 
222 #ifdef TST_TEST_H__
tst_fs_type(const char * path)223 static inline long tst_fs_type(const char *path)
224 {
225 	return tst_fs_type_(NULL, path);
226 }
227 
tst_fs_has_free(const char * path,unsigned int size,unsigned int mult)228 static inline int tst_fs_has_free(const char *path, unsigned int size,
229 				  unsigned int mult)
230 {
231 	return tst_fs_has_free_(NULL, path, size, mult);
232 }
233 
tst_fs_fill_hardlinks(const char * dir)234 static inline int tst_fs_fill_hardlinks(const char *dir)
235 {
236 	return tst_fs_fill_hardlinks_(NULL, dir);
237 }
238 
tst_fs_fill_subdirs(const char * dir)239 static inline int tst_fs_fill_subdirs(const char *dir)
240 {
241 	return tst_fs_fill_subdirs_(NULL, dir);
242 }
243 
tst_dir_is_empty(const char * name,int verbose)244 static inline int tst_dir_is_empty(const char *name, int verbose)
245 {
246 	return tst_dir_is_empty_(NULL, name, verbose);
247 }
248 #else
tst_fs_type(void (* cleanup)(void),const char * path)249 static inline long tst_fs_type(void (*cleanup)(void), const char *path)
250 {
251 	return tst_fs_type_(cleanup, path);
252 }
253 
tst_fs_has_free(void (* cleanup)(void),const char * path,unsigned int size,unsigned int mult)254 static inline int tst_fs_has_free(void (*cleanup)(void), const char *path,
255 				  unsigned int size, unsigned int mult)
256 {
257 	return tst_fs_has_free_(cleanup, path, size, mult);
258 }
259 
tst_fs_fill_hardlinks(void (* cleanup)(void),const char * dir)260 static inline int tst_fs_fill_hardlinks(void (*cleanup)(void), const char *dir)
261 {
262 	return tst_fs_fill_hardlinks_(cleanup, dir);
263 }
264 
tst_fs_fill_subdirs(void (* cleanup)(void),const char * dir)265 static inline int tst_fs_fill_subdirs(void (*cleanup)(void), const char *dir)
266 {
267 	return tst_fs_fill_subdirs_(cleanup, dir);
268 }
269 
tst_dir_is_empty(void (* cleanup)(void),const char * name,int verbose)270 static inline int tst_dir_is_empty(void (*cleanup)(void), const char *name, int verbose)
271 {
272 	return tst_dir_is_empty_(cleanup, name, verbose);
273 }
274 #endif
275 
276 #endif	/* TST_FS_H__ */
277