1 /* 2 * Copyright (c) 2015-2016 Cyril Hrubis <chrubis (at) 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 * allready 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 * Creates/ovewrites a file with specified pattern 142 * @path: path to file 143 * @pattern: pattern 144 * @bs: block size 145 * @bcount: blocks amount 146 */ 147 int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount); 148 149 150 #ifdef TST_TEST_H__ 151 static inline long tst_fs_type(const char *path) 152 { 153 return tst_fs_type_(NULL, path); 154 } 155 156 static inline int tst_fs_has_free(const char *path, unsigned int size, 157 unsigned int mult) 158 { 159 return tst_fs_has_free_(NULL, path, size, mult); 160 } 161 162 static inline int tst_fs_fill_hardlinks(const char *dir) 163 { 164 return tst_fs_fill_hardlinks_(NULL, dir); 165 } 166 167 static inline int tst_fs_fill_subdirs(const char *dir) 168 { 169 return tst_fs_fill_subdirs_(NULL, dir); 170 } 171 172 static inline int tst_dir_is_empty(const char *name, int verbose) 173 { 174 return tst_dir_is_empty_(NULL, name, verbose); 175 } 176 #else 177 static inline long tst_fs_type(void (*cleanup)(void), const char *path) 178 { 179 return tst_fs_type_(cleanup, path); 180 } 181 182 static inline int tst_fs_has_free(void (*cleanup)(void), const char *path, 183 unsigned int size, unsigned int mult) 184 { 185 return tst_fs_has_free_(cleanup, path, size, mult); 186 } 187 188 static inline int tst_fs_fill_hardlinks(void (*cleanup)(void), const char *dir) 189 { 190 return tst_fs_fill_hardlinks_(cleanup, dir); 191 } 192 193 static inline int tst_fs_fill_subdirs(void (*cleanup)(void), const char *dir) 194 { 195 return tst_fs_fill_subdirs_(cleanup, dir); 196 } 197 198 static inline int tst_dir_is_empty(void (*cleanup)(void), const char *name, int verbose) 199 { 200 return tst_dir_is_empty_(cleanup, name, verbose); 201 } 202 #endif 203 204 #endif /* TST_FS_H__ */ 205