Cyril Hrubis | bbdb9f7 | 2016-03-16 15:53:57 +0100 | [diff] [blame] | 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 | * 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__ */ |