]>
Commit | Line | Data |
---|---|---|
558d2836 A |
1 | #include <TargetConditionals.h> |
2 | ||
3 | #if !TARGET_OS_EMBEDDED | |
4 | ||
5 | #include <unistd.h> | |
6 | #include <sys/fcntl.h> | |
7 | #include <spawn.h> | |
8 | ||
9 | #include <Foundation/Foundation.h> | |
10 | ||
11 | #include "hfs-tests.h" | |
12 | #include "test-utils.h" | |
13 | #include "systemx.h" | |
14 | #include "disk-image.h" | |
15 | ||
16 | TEST(resize) | |
17 | ||
18 | static disk_image_t *di; | |
19 | ||
20 | #define DISK_IMAGE "/tmp/hfs_resize.sparseimage" | |
21 | ||
22 | int run_resize(__unused test_ctx_t *ctx) | |
23 | { | |
24 | di = disk_image_create(DISK_IMAGE, &(disk_image_opts_t){ | |
25 | .size = 100 * 1024 * 1024 | |
26 | }); | |
27 | ||
28 | int fd; | |
29 | ||
30 | // Create two fragmented files | |
31 | for (int i = 0; i < 2; ++i) { | |
32 | char *path; | |
33 | asprintf(&path, "%s/fragmented-file.%d", di->mount_point, i); | |
34 | ||
35 | fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 0666); | |
36 | assert_with_errno(fd >= 0); | |
37 | ||
38 | /* | |
39 | * First file we want near the end of the volume. Second file | |
40 | * at the beginning. | |
41 | */ | |
42 | fstore_t fstore = { | |
43 | .fst_flags = F_ALLOCATECONTIG | F_ALLOCATEALL, | |
44 | .fst_posmode = F_VOLPOSMODE, | |
45 | .fst_offset = i == 0 ? 80 * 1024 * 1024 : 4096, | |
46 | }; | |
47 | ||
48 | off_t len = 0; | |
49 | ||
50 | for (int j = 0; j < 64; ++j) { | |
51 | if (len) { | |
52 | struct log2phys l2p = { | |
53 | .l2p_contigbytes = 4096, | |
54 | .l2p_devoffset = len - 4096, | |
55 | }; | |
56 | ||
57 | assert_no_err(fcntl(fd, F_LOG2PHYS_EXT, &l2p)); | |
58 | ||
59 | fstore.fst_offset = l2p.l2p_devoffset + 16384; | |
60 | } | |
61 | ||
62 | len += 4096; | |
63 | ||
64 | fstore.fst_length = len; | |
65 | ||
66 | assert_no_err(fcntl(fd, F_PREALLOCATE, &fstore)); | |
67 | } | |
68 | ||
69 | assert_no_err(ftruncate(fd, len)); | |
70 | ||
71 | assert_no_err(close(fd)); | |
72 | } | |
73 | ||
74 | assert(!systemx("/usr/sbin/diskutil", SYSTEMX_QUIET, "resizeVolume", di->mount_point, "40m", NULL)); | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
79 | #endif // !TARGET_OS_EMBEDDED |