]> git.saurik.com Git - apple/hfs.git/blob - tests/cases/test-fsinfo.c
hfs-407.1.3.tar.gz
[apple/hfs.git] / tests / cases / test-fsinfo.c
1 /*
2 * Copyright (c) 2014 Apple, Inc. All rights reserved.
3 *
4 * Test HFS fsinfo fsctls
5 */
6
7 #include <sys/ioctl.h>
8 #include <sys/ioccom.h>
9 #include <sys/param.h>
10 #include <sys/mount.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/errno.h>
16 #include <spawn.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19
20 #include "../../core/hfs_fsctl.h"
21 #include "hfs-tests.h"
22 #include "test-utils.h"
23 #include "systemx.h"
24 #include "disk-image.h"
25
26 TEST(fsinfo, .run_as_root = true)
27
28 static disk_image_t *di;
29 char *srcdir;
30
31 #define KB *1024
32 #define MAX_FILES 100
33
34 static hfs_fsinfo fsinfo;
35
36 static void test_fsinfo_metadata_blocks(void)
37 {
38 bzero(&fsinfo, sizeof(fsinfo));
39 fsinfo.header.request_type = HFS_FSINFO_METADATA_BLOCKS_INFO;
40 fsinfo.header.version = HFS_FSINFO_VERSION;
41 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
42 }
43
44 static void test_fsinfo_metadata_extents(void)
45 {
46 bzero(&fsinfo, sizeof(fsinfo));
47 fsinfo.header.request_type = HFS_FSINFO_METADATA_EXTENTS;
48 fsinfo.header.version = HFS_FSINFO_VERSION;
49 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
50 }
51
52 static void test_fsinfo_metadata_percentfree(void)
53 {
54 bzero(&fsinfo, sizeof(fsinfo));
55 fsinfo.header.request_type = HFS_FSINFO_METADATA_PERCENTFREE;
56 fsinfo.header.version = HFS_FSINFO_VERSION;
57 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
58 }
59
60 static void test_fsinfo_file_extent_count(void)
61 {
62 bzero(&fsinfo, sizeof(fsinfo));
63 fsinfo.header.request_type = HFS_FSINFO_FILE_EXTENT_COUNT;
64 fsinfo.header.version = HFS_FSINFO_VERSION;
65 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
66 }
67
68 static void test_fsinfo_file_extent_size(void)
69 {
70 bzero(&fsinfo, sizeof(fsinfo));
71 fsinfo.header.request_type = HFS_FSINFO_FILE_EXTENT_SIZE;
72 fsinfo.header.version = HFS_FSINFO_VERSION;
73 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
74 }
75
76 static void test_fsinfo_file_size(void)
77 {
78
79 int fd;
80 unsigned buf_size;
81 void *buf = NULL;
82 struct hfs_fsinfo_data *fsinfo_data = &fsinfo.data;
83 unsigned long file_size_count;
84 unsigned i;
85 char *path[10];
86
87 bzero(&fsinfo, sizeof(fsinfo));
88 fsinfo.header.version = HFS_FSINFO_VERSION;
89 fsinfo.header.request_type = HFS_FSINFO_FILE_SIZE;
90 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
91 file_size_count = fsinfo_data->bucket[11];
92
93 buf_size = (1 KB);
94 buf = malloc(buf_size);
95 memset(buf, 0x83, buf_size);
96
97 for (i = 0; i < 10; i++)
98 {
99 asprintf(&path[i], "%s/fsinfo_test.data.%u", di->mount_point, i);
100 unlink(path[i]);
101 assert_with_errno((fd = open(path[i], O_RDWR | O_TRUNC | O_CREAT, 0666)) >= 0);
102 check_io(write(fd, buf, buf_size), buf_size);
103 close(fd);
104 }
105
106 bzero(&fsinfo, sizeof(fsinfo));
107 fsinfo.header.version = HFS_FSINFO_VERSION;
108 fsinfo.header.request_type = HFS_FSINFO_FILE_SIZE;
109 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
110
111 free(buf);
112
113 for (i = 0; i < 10; i++)
114 unlink(path[i]);
115
116 assert(fsinfo_data->bucket[11] >= (file_size_count + 5));
117 }
118
119
120 static void test_fsinfo_dir_valence(void)
121 {
122 unsigned long dir_size_count;
123 struct hfs_fsinfo_data *fsinfo_data = &fsinfo.data;
124 int fd;
125 char *dir_path[10], *path2;
126 unsigned i;
127
128 bzero(&fsinfo, sizeof(fsinfo));
129 fsinfo.header.version = HFS_FSINFO_VERSION;
130 fsinfo.header.request_type = HFS_FSINFO_DIR_VALENCE;
131 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
132 dir_size_count = fsinfo_data->bucket[4];
133
134 for (i = 0; i < 10; i++)
135 {
136 asprintf(&dir_path[i], "%s/fsinfo_test.dir_%u", di->mount_point, i);
137 assert_no_err(systemx("/bin/rm", "-rf", dir_path[i], NULL));
138 assert_no_err(mkdir(dir_path[i], 0777));
139
140 for (unsigned j = 0; j < 10; j++) {
141 asprintf(&path2, "%s/fsinfo_test.data.%u", dir_path[i], getpid()+j);
142 unlink(path2);
143 assert_with_errno((fd = open(path2, O_RDWR | O_TRUNC | O_CREAT, 0666)) >= 0);
144 close(fd);
145 }
146 }
147
148 bzero(&fsinfo, sizeof(fsinfo));
149 fsinfo.header.version = HFS_FSINFO_VERSION;
150 fsinfo.header.request_type = HFS_FSINFO_DIR_VALENCE;
151 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
152 for (i = 0; i < 10; i++)
153 assert_no_err(systemx("/bin/rm", "-rf", dir_path[i], NULL));
154
155 assert(fsinfo_data->bucket[4] >= (dir_size_count + 5));
156
157 }
158
159 static void test_fsinfo_name_size(void)
160 {
161 struct hfs_fsinfo_name *fsinfo_name = &fsinfo.name;
162 unsigned bucket_index;
163 unsigned long name_size_count;
164 char *filename = NULL;
165 int fd;
166 unsigned i;
167 char *path[10];
168
169 bzero(&fsinfo, sizeof(fsinfo));
170 fsinfo.header.version = HFS_FSINFO_VERSION;
171 fsinfo.header.request_type = HFS_FSINFO_NAME_SIZE;
172 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
173
174 for (i = 0; i < 10; i++)
175 {
176 asprintf(&path[i], "%s/hfs_fsinfo_test.data.txt_%u", di->mount_point, i);
177 unlink(path[i]);
178 filename = basename(path[i]);
179 assert_with_errno((fd = open(path[i], O_RDWR | O_TRUNC | O_CREAT, 0666)) >= 0);
180 close(fd);
181 }
182 bucket_index = (unsigned int)strlen(filename)/5;
183 name_size_count = fsinfo_name->bucket[bucket_index];
184
185 bzero(&fsinfo, sizeof(fsinfo));
186 fsinfo.header.version = HFS_FSINFO_VERSION;
187 fsinfo.header.request_type = HFS_FSINFO_NAME_SIZE;
188 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
189
190 for (i = 0; i < 10; i++)
191 unlink(path[i]);
192
193 assert(fsinfo_name->bucket[bucket_index] >= (name_size_count+5));
194
195 }
196
197 static void test_fsinfo_xattr_size(void)
198 {
199 bzero(&fsinfo, sizeof(fsinfo));
200 fsinfo.header.version = HFS_FSINFO_VERSION;
201 fsinfo.header.request_type = HFS_FSINFO_XATTR_SIZE;
202 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
203 }
204
205 static void test_fsinfo_free_extents(void)
206 {
207 bzero(&fsinfo, sizeof(fsinfo));
208 fsinfo.header.version = HFS_FSINFO_VERSION;
209 fsinfo.header.request_type = HFS_FSINFO_FREE_EXTENTS;
210 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
211
212 }
213
214 static void test_fsinfo_symlink_size(void)
215 {
216 char *symlink_path[10];
217 struct hfs_fsinfo_data *fsinfo_data = &fsinfo.data;
218 unsigned symlink_count = 0;
219 unsigned i;
220 char *path;
221
222 bzero(&fsinfo, sizeof(fsinfo));
223 fsinfo.header.version = HFS_FSINFO_VERSION;
224 fsinfo.header.request_type = HFS_FSINFO_SYMLINK_SIZE;
225 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
226 symlink_count = fsinfo_data->bucket[6];
227
228 asprintf(&path, "%s/fsinfo_test.data", di->mount_point);
229
230 for (i = 0; i < 10; i++)
231 {
232 asprintf(&symlink_path[i], "%s/fsinfo_test_link.%d", di->mount_point, i);
233 unlink(symlink_path[i]);
234 assert_no_err(systemx("/bin/ln", "-s", path, symlink_path[i], NULL));
235 }
236
237 bzero(&fsinfo, sizeof(fsinfo));
238 fsinfo.header.version = HFS_FSINFO_VERSION;
239 fsinfo.header.request_type = HFS_FSINFO_SYMLINK_SIZE;
240 assert_no_err(fsctl(di->mount_point, HFSIOC_GET_FSINFO, &fsinfo, 0));
241
242 for (i = 0; i < 10; i++)
243 unlink(symlink_path[i]);
244
245 assert(fsinfo_data->bucket[6] >= (symlink_count + 5));
246 }
247
248 static void setup_testvolume()
249 {
250 char *path;
251 int fd;
252 void *buf;
253
254 // Create a test folder with MAX_FILES files
255 assert_no_err(systemx("/bin/rm", "-rf", srcdir, NULL));
256 assert_no_err(mkdir(srcdir, 0777));
257
258 for (unsigned i = 0; i < MAX_FILES; i++) {
259 asprintf(&path, "%s/fsinfo_test.data.%u", srcdir, getpid()+i);
260 unlink(path);
261 assert_with_errno((fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 0666)) >= 0);
262 free(path);
263
264 unsigned buf_size = (1 KB) * (i + 1);
265 buf = malloc(buf_size);
266 memset(buf, 0x25, buf_size);
267 check_io(write(fd, buf, buf_size), buf_size);
268 free(buf);
269 close(fd);
270 }
271 }
272
273 int run_fsinfo(__unused test_ctx_t *ctx)
274 {
275
276 di = disk_image_get();
277 asprintf(&srcdir, "%s/fsinfo-test", di->mount_point);
278
279 setup_testvolume();
280
281 test_fsinfo_metadata_blocks();
282 test_fsinfo_metadata_extents();
283 test_fsinfo_metadata_percentfree();
284 test_fsinfo_file_extent_count();
285 test_fsinfo_file_extent_size();
286 test_fsinfo_file_size();
287 test_fsinfo_dir_valence();
288 test_fsinfo_name_size();
289 test_fsinfo_xattr_size();
290 test_fsinfo_free_extents();
291 test_fsinfo_symlink_size();
292
293 free(srcdir);
294
295 return 0;
296 }