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