12 #include "hfs-tests.h"
13 #include "test-utils.h"
14 #include "disk-image.h"
18 static disk_image_t
*di
;
20 pthread_mutex_t mutex
= PTHREAD_MUTEX_INITIALIZER
;
21 pthread_cond_t cond
= PTHREAD_COND_INITIALIZER
;
23 static volatile int state
;
24 static volatile bool run_thread
;
26 static char *file1
, *file2
;
28 void *read_thread(__unused
void *arg
)
30 int fd
= open(file1
, O_RDONLY
);
35 check_io(pread(fd
, &x
, 4, 0), 4);
40 pthread_mutex_lock(&mutex
);
42 pthread_mutex_unlock(&mutex
);
44 pthread_cond_broadcast(&cond
);
52 int run_uncached_io(__unused test_ctx_t
*ctx
)
54 di
= disk_image_get();
55 asprintf(&file1
, "%s/test.data", di
->mount_point
);
56 asprintf(&file2
, "%s/test2.data", di
->mount_point
);
62 assert_with_errno((fd
= open(file1
,
63 O_RDWR
| O_CREAT
| O_TRUNC
, 0666)) >= 0);
65 assert_no_err(fcntl(fd
, F_NOCACHE
, 1));
67 assert_no_err(ftruncate(fd
, 4096));
70 assert_with_errno((fd2
= open(file2
,
71 O_RDWR
| O_CREAT
| O_TRUNC
, 0666)) >= 0);
73 // Force the test file to be 1 block, and then 4 blocks
74 assert_no_err(ftruncate(fd2
, 4096));
75 assert_no_err(ftruncate(fd
, 4096 + 16384));
76 assert_no_err(ftruncate(fd2
, 8192));
78 char *buffer
= malloc(65536);
80 // Set buffer to be 12288 bytes off 16 KB alignment
81 buffer
= (char *)(((uintptr_t)(buffer
+ 4096) & ~16383) + 12288);
83 check_io(pwrite(fd
, buffer
, 32768, 0), 32768);
85 // Now do the (slightly simpler case: a single transaction)
86 assert_no_err(ftruncate(fd
, 0));
87 check_io(pwrite(fd
, buffer
, 32768, 0), 32768);
89 // And one more time with a single page
90 assert_no_err(ftruncate(fd
, 0));
91 check_io(pwrite(fd
, buffer
, 16384, 0), 16384);
93 // Now just two transactions
94 assert_no_err(ftruncate(fd
, 4096));
95 check_io(pwrite(fd
, buffer
, 32768, 0), 32768);
97 // And another variant of two transactions
98 assert_no_err(ftruncate(fd
, 0));
99 assert_no_err(ftruncate(fd
, 4096 + 16384));
100 assert_no_err(ftruncate(fd2
, 0));
101 assert_no_err(ftruncate(fd2
, 4096));
102 check_io(pwrite(fd
, buffer
, 32768, 0), 32768);
104 assert_no_err(close(fd
));
105 assert_no_err(unlink(file1
));
106 assert_no_err(unlink(file2
));
108 assert_with_errno((fd
= open(file1
,
109 O_RDWR
| O_CREAT
| O_TRUNC
, 0666)) >= 0);
111 // The cluster currently only does uncached I/O if 16 KB or higher
114 assert_no_err(ftruncate(fd
, size
));
116 assert_no_err(fcntl(fd
, F_NOCACHE
, 1));
120 bufs
[0] = (char *)(((uintptr_t)valloc(size
+ 65536) + 16383) & ~16383) + 4096;
121 bufs
[1] = valloc(size
);
123 for (int pass
= 0; pass
< 2; ++pass
) {
126 bzero(bufs
[0], size
);
127 memset(bufs
[1], 0xff, size
);
132 pthread_create(&thread
, NULL
, read_thread
, NULL
);
134 struct timeval start
;
135 gettimeofday(&start
, NULL
);
138 int cur_state
= state
;
142 check_io(pwrite(fd
, bufs
[cur_state
? 0 : 1], size
, 0), size
);
146 struct iovec iovs
[] = {
147 { bufs
[cur_state
? 0 : 1], size
/ 2 },
148 { bufs
[cur_state
? 0 : 1] + size
/ 2, size
/ 2 }
151 assert_no_err(lseek(fd
, 0, SEEK_SET
));
152 check_io(writev(fd
, iovs
, 2), size
);
156 pthread_mutex_lock(&mutex
);
157 while (state
== cur_state
) {
160 gettimeofday(&tv
, NULL
);
163 TIMEVAL_TO_TIMESPEC(&tv
, &ts
);
167 int res
= pthread_cond_timedwait(&cond
, &mutex
, &ts
);
174 pthread_mutex_unlock(&mutex
);
176 // If 10 seconds are up, we're done
177 struct timeval now
, elapsed
;
178 gettimeofday(&now
, NULL
);
179 timersub(&now
, &start
, &elapsed
);
180 if (elapsed
.tv_sec
>= 10)
185 pthread_join(thread
, NULL
);
188 assert_no_err(unlink(file1
));
190 assert_no_err (close(fd
));
191 assert_no_err (close(fd2
));