11static int sectors(
void) {
13 struct xa_file file = {.fd = -1};
14 struct stat initial, with_ea, after;
15 CHECK(!xa_create(&file, XA_EXT2, 0));
16 CHECK(!fstat(file.fd, &initial) && !initial.st_size);
17 CHECK(!fsetxattr(file.fd,
"user.first",
"a", 1, XATTR_CREATE));
18 CHECK(!fstat(file.fd, &with_ea));
19 CHECK(with_ea.st_size == 0 &&
20 with_ea.st_blocks == initial.st_blocks + (blkcnt_t)(xa_block / 512));
21 CHECK(!fsetxattr(file.fd,
"user.empty", NULL, 0, XATTR_CREATE));
22 CHECK(!fstat(file.fd, &after) && after.st_blocks == with_ea.st_blocks);
23 CHECK(!fremovexattr(file.fd,
"user.first"));
24 CHECK(!xa_value(&file, XA_FD,
"user.empty", NULL, 0));
25 CHECK(!fstat(file.fd, &after) && after.st_blocks == with_ea.st_blocks);
26 CHECK(!fremovexattr(file.fd,
"user.empty"));
27 CHECK(!fstat(file.fd, &after) && !after.st_size && after.st_blocks == initial.st_blocks);
28 CHECK(!xa_names(&file, XA_FD, NULL, 0));
29 CHECK(!fsetxattr(file.fd,
"user.reused",
"b", 1, XATTR_CREATE));
30 CHECK(!fstat(file.fd, &after) && after.st_blocks == with_ea.st_blocks);
36static int capacity_and_resize(
void) {
37 int failed = 0, alias = -1;
38 struct xa_file file = {.fd = -1};
39 const size_t original_size = xa_block + 137, grown_size = xa_block + 211;
40 unsigned char *data = NULL, *actual = NULL, *large = NULL;
41 struct stat before, after;
42 static const unsigned char value[] = {0, 0xff, 7, 0, 3};
43 const char* names[] = {
"user.keep"};
44 data = malloc(original_size);
45 actual = malloc(grown_size);
46 large = malloc(xa_block + 1);
47 CHECK(data && actual && large);
48 for (
size_t n = 0; n < original_size; ++n)
49 data[n] = (
unsigned char)(n * 37 + 11);
50 memset(large, 0xa3, xa_block + 1);
51 CHECK(!xa_create(&file, XA_EXT2, 0));
52 CHECK(!xa_write_all(file.fd, data, original_size));
53 CHECK(!fsetxattr(file.fd,
"user.keep", value,
sizeof(value), XATTR_CREATE));
54 CHECK(!fstat(file.fd, &before));
56 CHECK(fsetxattr(file.fd,
"user.keep", large, xa_block + 1, XATTR_REPLACE) == -1 &&
57 errno == (xa_block == 65536 ? E2BIG : ERANGE));
59 CHECK(fsetxattr(file.fd,
"user.keep", large, xa_block, XATTR_REPLACE) == -1 && errno == ENOSPC);
61 CHECK(fsetxattr(file.fd,
"user.no-space", large, xa_block, XATTR_CREATE) == -1 &&
63 CHECK(!fstat(file.fd, &after));
64 CHECK(after.st_size == before.st_size && after.st_blocks == before.st_blocks &&
65 after.st_ctim.tv_sec == before.st_ctim.tv_sec &&
66 after.st_ctim.tv_nsec == before.st_ctim.tv_nsec);
67 CHECK(!xa_value(&file, XA_FD,
"user.keep", value,
sizeof(value)));
68 CHECK(!xa_names(&file, XA_FD, names, 1));
69 CHECK(pread(file.fd, actual, original_size, 0) == (ssize_t)original_size &&
70 !memcmp(actual, data, original_size));
71 alias = xa_open_alias(&file);
73 CHECK(!ftruncate(alias, 137));
74 CHECK(!xa_value(&file, XA_FD,
"user.keep", value,
sizeof(value)));
75 CHECK(!ftruncate(alias, grown_size));
76 CHECK(!fstat(file.fd, &after) && after.st_size == (off_t)grown_size);
77 memset(actual, 0xa5, grown_size);
78 CHECK(pread(file.fd, actual, grown_size, 0) == (ssize_t)grown_size);
79 CHECK(!memcmp(actual, data, 137));
80 for (
size_t n = 137; n < grown_size; ++n)
81 CHECK(actual[n] == 0);
82 CHECK(!xa_value(&file, XA_PATH,
"user.keep", value,
sizeof(value)));
83 CHECK(!xa_names(&file, XA_PATH, names, 1));
84 CHECK(!ftruncate(file.fd, 0));
85 CHECK(!fstat(alias, &after) && !after.st_size && after.st_blocks == (blkcnt_t)(xa_block / 512));
86 CHECK(!fremovexattr(alias,
"user.keep"));
87 CHECK(!fstat(file.fd, &after) && !after.st_size && !after.st_blocks);
99 return sectors() || capacity_and_resize();