1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <errno.h>
6
7 #include <fbl/algorithm.h>
8
9 #include "util.h"
10
11 #define MB (1 << 20)
12 #define PRINT_SIZE (MB * 100)
13
test_maxfile(void)14 bool test_maxfile(void) {
15 BEGIN_TEST;
16
17 int fd = emu_open("::bigfile", O_CREAT | O_RDWR, 0644);
18 ASSERT_GT(fd, 0);
19 char data_a[8192];
20 char data_b[8192];
21 char data_c[8192];
22 memset(data_a, 0xaa, sizeof(data_a));
23 memset(data_b, 0xbb, sizeof(data_b));
24 memset(data_c, 0xcc, sizeof(data_c));
25 ssize_t sz = 0;
26 ssize_t r;
27
28 auto rotate = [&](const char* data) {
29 if (data == data_a) {
30 return data_b;
31 } else if (data == data_b) {
32 return data_c;
33 } else {
34 return data_a;
35 }
36 };
37
38 const char* data = data_a;
39 for (;;) {
40 if ((r = emu_write(fd, data, sizeof(data_a))) < 0) {
41 fprintf(stderr, "bigfile received error: %s\n", strerror(errno));
42 if ((errno == EFBIG) || (errno == ENOSPC)) {
43 // Either the file should be too big (EFBIG) or the file should
44 // consume the whole volume (ENOSPC).
45 fprintf(stderr, "(This was an expected error)\n");
46 r = 0;
47 }
48 break;
49 }
50 if ((sz + r) % PRINT_SIZE < (sz % PRINT_SIZE)) {
51 fprintf(stderr, "wrote %zu MB\n", static_cast<size_t>((sz + r) / MB));
52 }
53 sz += r;
54 if (r < (ssize_t)(sizeof(data_a))) {
55 fprintf(stderr, "bigfile write short write of %ld bytes\n", r);
56 break;
57 }
58
59 // Rotate which data buffer we use
60 data = rotate(data);
61 }
62 ASSERT_EQ(r, 0, "Saw an unexpected error from write");
63
64 struct stat buf;
65 ASSERT_EQ(emu_fstat(fd, &buf), 0, "Couldn't stat max file");
66 ASSERT_EQ(buf.st_size, sz, "Unexpected max file size");
67
68 // Try closing, re-opening, and verifying the file
69 ASSERT_EQ(emu_close(fd), 0);
70 fd = emu_open("::bigfile", O_RDWR, 0644);
71 char readbuf[8192];
72 ssize_t bytes_read = 0;
73 data = data_a;
74 while (bytes_read < sz) {
75 r = emu_read(fd, readbuf, sizeof(readbuf));
76 ASSERT_EQ(r, fbl::min(sz - bytes_read, static_cast<ssize_t>(sizeof(readbuf))));
77 ASSERT_EQ(memcmp(readbuf, data, r), 0, "File failed to verify");
78 data = rotate(data);
79 bytes_read += r;
80 }
81
82 ASSERT_EQ(bytes_read, sz);
83
84 ASSERT_EQ(emu_close(fd), 0);
85 ASSERT_EQ(run_fsck(), 0);
86 END_TEST;
87 }
88
89 RUN_MINFS_TESTS(maxfile_tests,
90 RUN_TEST_LARGE(test_maxfile)
91 )
92