2 * Copyright (c) 2014 Apple, Inc. All rights reserved.
4 * Test HFS fsinfo fsctls
8 #include <sys/ioccom.h>
10 #include <sys/mount.h>
15 #include <sys/errno.h>
20 #include "../../core/hfs_fsctl.h"
21 #include "hfs-tests.h"
22 #include "test-utils.h"
24 #include "disk-image.h"
26 TEST(fsinfo
, .run_as_root
= true)
28 static disk_image_t
*di
;
34 static hfs_fsinfo fsinfo
;
36 static void test_fsinfo_metadata_blocks(void)
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));
44 static void test_fsinfo_metadata_extents(void)
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));
52 static void test_fsinfo_metadata_percentfree(void)
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));
60 static void test_fsinfo_file_extent_count(void)
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));
68 static void test_fsinfo_file_extent_size(void)
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));
76 static void test_fsinfo_file_size(void)
82 struct hfs_fsinfo_data
*fsinfo_data
= &fsinfo
.data
;
83 unsigned long file_size_count
;
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];
94 buf
= malloc(buf_size
);
95 memset(buf
, 0x83, buf_size
);
97 for (i
= 0; i
< 10; i
++)
99 asprintf(&path
[i
], "%s/fsinfo_test.data.%u", di
->mount_point
, 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
);
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));
113 for (i
= 0; i
< 10; i
++)
116 assert(fsinfo_data
->bucket
[11] >= (file_size_count
+ 5));
120 static void test_fsinfo_dir_valence(void)
122 unsigned long dir_size_count
;
123 struct hfs_fsinfo_data
*fsinfo_data
= &fsinfo
.data
;
125 char *dir_path
[10], *path2
;
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];
134 for (i
= 0; i
< 10; i
++)
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));
140 for (unsigned j
= 0; j
< 10; j
++) {
141 asprintf(&path2
, "%s/fsinfo_test.data.%u", dir_path
[i
], getpid()+j
);
143 assert_with_errno((fd
= open(path2
, O_RDWR
| O_TRUNC
| O_CREAT
, 0666)) >= 0);
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
));
155 assert(fsinfo_data
->bucket
[4] >= (dir_size_count
+ 5));
159 static void test_fsinfo_name_size(void)
161 struct hfs_fsinfo_name
*fsinfo_name
= &fsinfo
.name
;
162 unsigned bucket_index
;
163 unsigned long name_size_count
;
164 char *filename
= NULL
;
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));
174 for (i
= 0; i
< 10; i
++)
176 asprintf(&path
[i
], "%s/hfs_fsinfo_test.data.txt_%u", di
->mount_point
, i
);
178 filename
= basename(path
[i
]);
179 assert_with_errno((fd
= open(path
[i
], O_RDWR
| O_TRUNC
| O_CREAT
, 0666)) >= 0);
182 bucket_index
= (unsigned int)strlen(filename
)/5;
183 name_size_count
= fsinfo_name
->bucket
[bucket_index
];
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));
190 for (i
= 0; i
< 10; i
++)
193 assert(fsinfo_name
->bucket
[bucket_index
] >= (name_size_count
+5));
197 static void test_fsinfo_xattr_size(void)
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));
205 static void test_fsinfo_free_extents(void)
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));
214 static void test_fsinfo_symlink_size(void)
216 char *symlink_path
[10];
217 struct hfs_fsinfo_data
*fsinfo_data
= &fsinfo
.data
;
218 unsigned symlink_count
= 0;
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];
228 asprintf(&path
, "%s/fsinfo_test.data", di
->mount_point
);
230 for (i
= 0; i
< 10; i
++)
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
));
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));
242 for (i
= 0; i
< 10; i
++)
243 unlink(symlink_path
[i
]);
245 assert(fsinfo_data
->bucket
[6] >= (symlink_count
+ 5));
248 static void setup_testvolume()
252 void *buf
= malloc(1 KB
);
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));
258 for (unsigned i
= 0; i
< MAX_FILES
; i
++) {
259 asprintf(&path
, "%s/fsinfo_test.data.%u", srcdir
, getpid()+i
);
261 assert_with_errno((fd
= open(path
, O_RDWR
| O_TRUNC
| O_CREAT
, 0666)) >= 0);
264 unsigned buf_size
= (1 KB
) * i
;
265 buf
= malloc(buf_size
);
266 memset(buf
, 0x25, buf_size
);
267 check_io(write(fd
, buf
, buf_size
), buf_size
);
271 int run_fsinfo(__unused test_ctx_t
*ctx
)
274 di
= disk_image_get();
275 asprintf(&srcdir
, "%s/fsinfo-test", di
->mount_point
);
279 test_fsinfo_metadata_blocks();
280 test_fsinfo_metadata_extents();
281 test_fsinfo_metadata_percentfree();
282 test_fsinfo_file_extent_count();
283 test_fsinfo_file_extent_size();
284 test_fsinfo_file_size();
285 test_fsinfo_dir_valence();
286 test_fsinfo_name_size();
287 test_fsinfo_xattr_size();
288 test_fsinfo_free_extents();
289 test_fsinfo_symlink_size();