• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
45 enum {
46 	TST_BYTES = 1,
47 	TST_KB = 1024,
48 	TST_MB = 1048576,
49 	TST_GB = 1073741824,
50 };
51 
52 /*
53  * @path: path is the pathname of any file within the mounted file system
54  * @mult: mult should be TST_KB, TST_MB or TST_GB
55  * the required free space is calculated by @size * @mult
56  */
57 int tst_fs_has_free_(void (*cleanup)(void), const char *path,
58                      unsigned int size, unsigned int mult);
59 
60 /*
61  * Returns filesystem magick for a given path.
62  *
63  * The expected usage is:
64  *
65  *      if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
66  *		tst_brkm(TCONF, cleanup,
67  *		         "Test not supported on NFS filesystem");
68  *	}
69  *
70  * Or:
71  *
72  *	long type;
73  *
74  *	swtich ((type = tst_fs_type(cleanup, "."))) {
75  *	case TST_NFS_MAGIC:
76  *	case TST_TMPFS_MAGIC:
77  *	case TST_RAMFS_MAGIC:
78  *		tst_brkm(TCONF, cleanup, "Test not supported on %s filesystem",
79  *		         tst_fs_type_name(type));
80  *	break;
81  *	}
82  */
83 long tst_fs_type_(void (*cleanup)(void), const char *path);
84 
85 /*
86  * Returns filesystem name given magic.
87  */
88 const char *tst_fs_type_name(long f_type);
89 
90 /*
91  * Try to get maximum number of hard links to a regular file inside the @dir.
92  *
93  * Note: This number depends on the filesystem @dir is on.
94  *
95  * The code uses link(2) to create hard links to a single file until it gets
96  * EMLINK or creates 65535 links.
97  *
98  * If limit is hit maximal number of hardlinks is returned and the the @dir is
99  * filled with hardlinks in format "testfile%i" where i belongs to [0, limit)
100  * interval.
101  *
102  * If no limit is hit (succed to create 65535 without error) or if link()
103  * failed with ENOSPC or EDQUOT zero is returned previously created files are
104  * removed.
105  */
106 int tst_fs_fill_hardlinks_(void (*cleanup) (void), const char *dir);
107 
108 /*
109  * Try to get maximum number of subdirectories in directory.
110  *
111  * Note: This number depends on the filesystem @dir is on.
112  *
113  * The code uses mkdir(2) to create directories in @dir until it gets EMLINK
114  * or creates 65535 directories.
115  *
116  * If limit is hit the maximal number of subdirectories is returned and the
117  * @dir is filled with subdirectories in format "testdir%i" where i belongs to
118  * [0, limit - 2) interval (because each newly created dir has two links
119  * already the '.' and link from parent dir).
120  *
121  * If no limit is hit or mkdir() failed with ENOSPC or EDQUOT zero is returned
122  * previously created directories are removed.
123  *
124  */
125 int tst_fs_fill_subdirs_(void (*cleanup) (void), const char *dir);
126 
127 /*
128  * Checks if a given directory contains any entities,
129  * returns 1 if directory is empty, 0 otherwise
130  */
131 int tst_dir_is_empty_(void (*cleanup)(void), const char *name, int verbose);
132 
133 /*
134  * Search $PATH for prog_name and fills buf with absolute path if found.
135  *
136  * Returns -1 on failure, either command was not found or buffer was too small.
137  */
138 int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
139 
140 /*
141  * Fill a file with specified pattern
142  * @fd: file descriptor
143  * @pattern: pattern
144  * @bs: block size
145  * @bcount: blocks count
146  */
147 int tst_fill_fd(int fd, char pattern, size_t bs, size_t bcount);
148 
149 /*
150  * Creates/ovewrites a file with specified pattern
151  * @path: path to file
152  * @pattern: pattern
153  * @bs: block size
154  * @bcount: blocks amount
155  */
156 int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
157 
158 /*
159  * Return 1 if a specified fiilsystem is supported
160  * Return 0 if a specified fiilsystem isn't supported
161  */
162 int tst_fs_is_supported(const char *fs_type);
163 
164 /*
165  * Returns NULL-terminated array of kernel-supported filesystems.
166  */
167 const char **tst_get_supported_fs_types(void);
168 
169 /*
170  * Creates and writes to files on given path until write fails with ENOSPC
171  */
172 void tst_fill_fs(const char *path, int verbose);
173 
174 #ifdef TST_TEST_H__
tst_fs_type(const char * path)175 static inline long tst_fs_type(const char *path)
176 {
177 	return tst_fs_type_(NULL, path);
178 }
179 
tst_fs_has_free(const char * path,unsigned int size,unsigned int mult)180 static inline int tst_fs_has_free(const char *path, unsigned int size,
181                                   unsigned int mult)
182 {
183 	return tst_fs_has_free_(NULL, path, size, mult);
184 }
185 
tst_fs_fill_hardlinks(const char * dir)186 static inline int tst_fs_fill_hardlinks(const char *dir)
187 {
188 	return tst_fs_fill_hardlinks_(NULL, dir);
189 }
190 
tst_fs_fill_subdirs(const char * dir)191 static inline int tst_fs_fill_subdirs(const char *dir)
192 {
193 	return tst_fs_fill_subdirs_(NULL, dir);
194 }
195 
tst_dir_is_empty(const char * name,int verbose)196 static inline int tst_dir_is_empty(const char *name, int verbose)
197 {
198 	return tst_dir_is_empty_(NULL, name, verbose);
199 }
200 #else
tst_fs_type(void (* cleanup)(void),const char * path)201 static inline long tst_fs_type(void (*cleanup)(void), const char *path)
202 {
203 	return tst_fs_type_(cleanup, path);
204 }
205 
tst_fs_has_free(void (* cleanup)(void),const char * path,unsigned int size,unsigned int mult)206 static inline int tst_fs_has_free(void (*cleanup)(void), const char *path,
207                                   unsigned int size, unsigned int mult)
208 {
209 	return tst_fs_has_free_(cleanup, path, size, mult);
210 }
211 
tst_fs_fill_hardlinks(void (* cleanup)(void),const char * dir)212 static inline int tst_fs_fill_hardlinks(void (*cleanup)(void), const char *dir)
213 {
214 	return tst_fs_fill_hardlinks_(cleanup, dir);
215 }
216 
tst_fs_fill_subdirs(void (* cleanup)(void),const char * dir)217 static inline int tst_fs_fill_subdirs(void (*cleanup)(void), const char *dir)
218 {
219 	return tst_fs_fill_subdirs_(cleanup, dir);
220 }
221 
tst_dir_is_empty(void (* cleanup)(void),const char * name,int verbose)222 static inline int tst_dir_is_empty(void (*cleanup)(void), const char *name, int verbose)
223 {
224 	return tst_dir_is_empty_(cleanup, name, verbose);
225 }
226 #endif
227 
228 #endif	/* TST_FS_H__ */
229