t_io.c revision 1.13 1 1.13 riastrad /* $NetBSD: t_io.c,v 1.13 2015/03/28 16:17:25 riastradh Exp $ */
2 1.1 pooka
3 1.1 pooka /*-
4 1.1 pooka * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.1 pooka * All rights reserved.
6 1.1 pooka *
7 1.1 pooka * Redistribution and use in source and binary forms, with or without
8 1.1 pooka * modification, are permitted provided that the following conditions
9 1.1 pooka * are met:
10 1.1 pooka * 1. Redistributions of source code must retain the above copyright
11 1.1 pooka * notice, this list of conditions and the following disclaimer.
12 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 pooka * notice, this list of conditions and the following disclaimer in the
14 1.1 pooka * documentation and/or other materials provided with the distribution.
15 1.1 pooka *
16 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 pooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 pooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 pooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 pooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 pooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 pooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 pooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 pooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 pooka * POSSIBILITY OF SUCH DAMAGE.
27 1.1 pooka */
28 1.1 pooka
29 1.1 pooka #include <sys/stat.h>
30 1.1 pooka #include <sys/statvfs.h>
31 1.1 pooka
32 1.1 pooka #include <atf-c.h>
33 1.1 pooka #include <fcntl.h>
34 1.1 pooka #include <libgen.h>
35 1.1 pooka #include <stdlib.h>
36 1.1 pooka #include <unistd.h>
37 1.1 pooka
38 1.1 pooka #include <rump/rump_syscalls.h>
39 1.1 pooka #include <rump/rump.h>
40 1.1 pooka
41 1.1 pooka #include "../common/h_fsmacros.h"
42 1.1 pooka #include "../../h_macros.h"
43 1.1 pooka
44 1.3 pooka #define TESTSTR "this is a string. collect enough and you'll have Em"
45 1.3 pooka #define TESTSZ sizeof(TESTSTR)
46 1.3 pooka
47 1.1 pooka static void
48 1.1 pooka holywrite(const atf_tc_t *tc, const char *mp)
49 1.1 pooka {
50 1.1 pooka char buf[1024];
51 1.1 pooka char *b2, *b3;
52 1.1 pooka size_t therange = getpagesize()+1;
53 1.1 pooka int fd;
54 1.1 pooka
55 1.3 pooka FSTEST_ENTER();
56 1.1 pooka
57 1.1 pooka RL(fd = rump_sys_open("file", O_RDWR|O_CREAT|O_TRUNC, 0666));
58 1.1 pooka
59 1.1 pooka memset(buf, 'A', sizeof(buf));
60 1.1 pooka RL(rump_sys_pwrite(fd, buf, 1, getpagesize()));
61 1.1 pooka
62 1.1 pooka memset(buf, 'B', sizeof(buf));
63 1.6 pooka RL(rump_sys_pwrite(fd, buf, 2, getpagesize()-1));
64 1.1 pooka
65 1.1 pooka REQUIRE_LIBC(b2 = malloc(2 * getpagesize()), NULL);
66 1.1 pooka REQUIRE_LIBC(b3 = malloc(2 * getpagesize()), NULL);
67 1.1 pooka
68 1.1 pooka RL(rump_sys_pread(fd, b2, therange, 0));
69 1.1 pooka
70 1.1 pooka memset(b3, 0, therange);
71 1.1 pooka memset(b3 + getpagesize() - 1, 'B', 2);
72 1.1 pooka
73 1.2 pooka ATF_REQUIRE_EQ(memcmp(b2, b3, therange), 0);
74 1.1 pooka
75 1.1 pooka rump_sys_close(fd);
76 1.3 pooka FSTEST_EXIT();
77 1.3 pooka }
78 1.3 pooka
79 1.3 pooka static void
80 1.3 pooka extendbody(const atf_tc_t *tc, off_t seekcnt)
81 1.3 pooka {
82 1.3 pooka char buf[TESTSZ+1];
83 1.3 pooka struct stat sb;
84 1.3 pooka int fd;
85 1.3 pooka
86 1.3 pooka FSTEST_ENTER();
87 1.3 pooka RL(fd = rump_sys_open("testfile",
88 1.3 pooka O_CREAT | O_RDWR | (seekcnt ? O_APPEND : 0)));
89 1.3 pooka RL(rump_sys_ftruncate(fd, seekcnt));
90 1.3 pooka RL(rump_sys_fstat(fd, &sb));
91 1.3 pooka ATF_REQUIRE_EQ(sb.st_size, seekcnt);
92 1.3 pooka
93 1.3 pooka ATF_REQUIRE_EQ(rump_sys_write(fd, TESTSTR, TESTSZ), TESTSZ);
94 1.3 pooka ATF_REQUIRE_EQ(rump_sys_pread(fd, buf, TESTSZ, seekcnt), TESTSZ);
95 1.3 pooka ATF_REQUIRE_STREQ(buf, TESTSTR);
96 1.3 pooka
97 1.3 pooka RL(rump_sys_fstat(fd, &sb));
98 1.5 pooka ATF_REQUIRE_EQ(sb.st_size, (off_t)TESTSZ + seekcnt);
99 1.3 pooka RL(rump_sys_close(fd));
100 1.3 pooka FSTEST_EXIT();
101 1.3 pooka }
102 1.3 pooka
103 1.3 pooka static void
104 1.3 pooka extendfile(const atf_tc_t *tc, const char *mp)
105 1.3 pooka {
106 1.3 pooka
107 1.3 pooka extendbody(tc, 0);
108 1.3 pooka }
109 1.3 pooka
110 1.3 pooka static void
111 1.3 pooka extendfile_append(const atf_tc_t *tc, const char *mp)
112 1.3 pooka {
113 1.3 pooka
114 1.3 pooka extendbody(tc, 37);
115 1.1 pooka }
116 1.1 pooka
117 1.7 pooka static void
118 1.7 pooka overwritebody(const atf_tc_t *tc, off_t count, bool dotrunc)
119 1.7 pooka {
120 1.7 pooka char *buf;
121 1.7 pooka int fd;
122 1.7 pooka
123 1.7 pooka REQUIRE_LIBC(buf = malloc(count), NULL);
124 1.7 pooka FSTEST_ENTER();
125 1.11 pooka RL(fd = rump_sys_open("testi", O_CREAT | O_RDWR, 0666));
126 1.7 pooka ATF_REQUIRE_EQ(rump_sys_write(fd, buf, count), count);
127 1.7 pooka RL(rump_sys_close(fd));
128 1.7 pooka
129 1.11 pooka RL(fd = rump_sys_open("testi", O_RDWR));
130 1.7 pooka if (dotrunc)
131 1.7 pooka RL(rump_sys_ftruncate(fd, 0));
132 1.7 pooka ATF_REQUIRE_EQ(rump_sys_write(fd, buf, count), count);
133 1.7 pooka RL(rump_sys_close(fd));
134 1.7 pooka FSTEST_EXIT();
135 1.7 pooka }
136 1.7 pooka
137 1.7 pooka static void
138 1.7 pooka overwrite512(const atf_tc_t *tc, const char *mp)
139 1.7 pooka {
140 1.7 pooka
141 1.7 pooka overwritebody(tc, 512, false);
142 1.7 pooka }
143 1.7 pooka
144 1.7 pooka static void
145 1.7 pooka overwrite64k(const atf_tc_t *tc, const char *mp)
146 1.7 pooka {
147 1.7 pooka
148 1.7 pooka overwritebody(tc, 1<<16, false);
149 1.7 pooka }
150 1.7 pooka
151 1.7 pooka static void
152 1.7 pooka overwrite_trunc(const atf_tc_t *tc, const char *mp)
153 1.7 pooka {
154 1.7 pooka
155 1.7 pooka overwritebody(tc, 1<<16, true);
156 1.7 pooka }
157 1.7 pooka
158 1.8 njoly static void
159 1.8 njoly shrinkfile(const atf_tc_t *tc, const char *mp)
160 1.8 njoly {
161 1.8 njoly int fd;
162 1.8 njoly
163 1.8 njoly FSTEST_ENTER();
164 1.8 njoly RL(fd = rump_sys_open("file", O_RDWR|O_CREAT|O_TRUNC, 0666));
165 1.8 njoly RL(rump_sys_ftruncate(fd, 2));
166 1.8 njoly RL(rump_sys_ftruncate(fd, 1));
167 1.8 njoly rump_sys_close(fd);
168 1.8 njoly FSTEST_EXIT();
169 1.8 njoly }
170 1.8 njoly
171 1.12 pooka #define TBSIZE 9000
172 1.12 pooka static void
173 1.12 pooka read_after_unlink(const atf_tc_t *tc, const char *mp)
174 1.12 pooka {
175 1.12 pooka char buf[TBSIZE], buf2[TBSIZE];
176 1.12 pooka int fd;
177 1.12 pooka
178 1.12 pooka FSTEST_ENTER();
179 1.12 pooka
180 1.12 pooka /* create file and put some content into it */
181 1.12 pooka RL(fd = rump_sys_open("file", O_RDWR|O_CREAT, 0666));
182 1.12 pooka memset(buf, 'D', TBSIZE);
183 1.12 pooka ATF_REQUIRE_EQ(rump_sys_write(fd, buf, TBSIZE), TBSIZE);
184 1.12 pooka rump_sys_close(fd);
185 1.12 pooka
186 1.12 pooka /* flush buffers from UBC to file system */
187 1.12 pooka ATF_REQUIRE_ERRNO(EBUSY, rump_sys_unmount(mp, 0) == -1);
188 1.12 pooka
189 1.12 pooka RL(fd = rump_sys_open("file", O_RDWR));
190 1.12 pooka RL(rump_sys_unlink("file"));
191 1.12 pooka
192 1.12 pooka ATF_REQUIRE_EQ(rump_sys_read(fd, buf2, TBSIZE), TBSIZE);
193 1.12 pooka ATF_REQUIRE_EQ(memcmp(buf, buf2, TBSIZE), 0);
194 1.12 pooka rump_sys_close(fd);
195 1.12 pooka
196 1.12 pooka FSTEST_EXIT();
197 1.12 pooka }
198 1.12 pooka
199 1.12 pooka static void
200 1.12 pooka wrrd_after_unlink(const atf_tc_t *tc, const char *mp)
201 1.12 pooka {
202 1.12 pooka int value = 0x11;
203 1.12 pooka int v2;
204 1.12 pooka int fd;
205 1.12 pooka
206 1.12 pooka FSTEST_ENTER();
207 1.12 pooka
208 1.12 pooka RL(fd = rump_sys_open("file", O_RDWR|O_CREAT, 0666));
209 1.12 pooka RL(rump_sys_unlink("file"));
210 1.12 pooka
211 1.12 pooka RL(rump_sys_pwrite(fd, &value, sizeof(value), 654321));
212 1.12 pooka
213 1.12 pooka /*
214 1.12 pooka * We can't easily invalidate the buffer since we hold a
215 1.12 pooka * reference, but try to get them to flush anyway.
216 1.12 pooka */
217 1.12 pooka RL(rump_sys_fsync(fd));
218 1.12 pooka RL(rump_sys_pread(fd, &v2, sizeof(v2), 654321));
219 1.12 pooka rump_sys_close(fd);
220 1.12 pooka
221 1.12 pooka ATF_REQUIRE_EQ(value, v2);
222 1.12 pooka FSTEST_EXIT();
223 1.12 pooka }
224 1.12 pooka
225 1.13 riastrad static void
226 1.13 riastrad read_fault(const atf_tc_t *tc, const char *mp)
227 1.13 riastrad {
228 1.13 riastrad char ch = 123;
229 1.13 riastrad int fd;
230 1.13 riastrad
231 1.13 riastrad FSTEST_ENTER();
232 1.13 riastrad RL(fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777));
233 1.13 riastrad ATF_REQUIRE_EQ(rump_sys_write(fd, &ch, 1), 1);
234 1.13 riastrad RL(rump_sys_close(fd));
235 1.13 riastrad RL(fd = rump_sys_open("file", O_RDONLY | O_SYNC | O_RSYNC));
236 1.13 riastrad if (FSTYPE_EXT2FS(tc) ||
237 1.13 riastrad FSTYPE_FFS(tc) ||
238 1.13 riastrad FSTYPE_FFSLOG(tc) ||
239 1.13 riastrad FSTYPE_LFS(tc) ||
240 1.13 riastrad FSTYPE_MSDOS(tc) ||
241 1.13 riastrad FSTYPE_P2K_FFS(tc) ||
242 1.13 riastrad FSTYPE_SYSVBFS(tc))
243 1.13 riastrad atf_tc_expect_fail("bad sync atime update code path");
244 1.13 riastrad ATF_REQUIRE_ERRNO(EFAULT, rump_sys_read(fd, NULL, 1) == -1);
245 1.13 riastrad RL(rump_sys_close(fd));
246 1.13 riastrad FSTEST_EXIT();
247 1.13 riastrad }
248 1.13 riastrad
249 1.1 pooka ATF_TC_FSAPPLY(holywrite, "create a sparse file and fill hole");
250 1.3 pooka ATF_TC_FSAPPLY(extendfile, "check that extending a file works");
251 1.3 pooka ATF_TC_FSAPPLY(extendfile_append, "check that extending a file works "
252 1.9 jruoho "with a append-only fd (PR kern/44307)");
253 1.7 pooka ATF_TC_FSAPPLY(overwrite512, "write a 512 byte file twice");
254 1.7 pooka ATF_TC_FSAPPLY(overwrite64k, "write a 64k byte file twice");
255 1.7 pooka ATF_TC_FSAPPLY(overwrite_trunc, "write 64k + truncate + rewrite");
256 1.8 njoly ATF_TC_FSAPPLY(shrinkfile, "shrink file");
257 1.12 pooka ATF_TC_FSAPPLY(read_after_unlink, "contents can be read off disk after unlink");
258 1.12 pooka ATF_TC_FSAPPLY(wrrd_after_unlink, "file can be written and read after unlink");
259 1.13 riastrad ATF_TC_FSAPPLY(read_fault, "read at bad address must return EFAULT");
260 1.1 pooka
261 1.1 pooka ATF_TP_ADD_TCS(tp)
262 1.1 pooka {
263 1.1 pooka
264 1.1 pooka ATF_TP_FSAPPLY(holywrite);
265 1.3 pooka ATF_TP_FSAPPLY(extendfile);
266 1.3 pooka ATF_TP_FSAPPLY(extendfile_append);
267 1.7 pooka ATF_TP_FSAPPLY(overwrite512);
268 1.7 pooka ATF_TP_FSAPPLY(overwrite64k);
269 1.7 pooka ATF_TP_FSAPPLY(overwrite_trunc);
270 1.8 njoly ATF_TP_FSAPPLY(shrinkfile);
271 1.12 pooka ATF_TP_FSAPPLY(read_after_unlink);
272 1.12 pooka ATF_TP_FSAPPLY(wrrd_after_unlink);
273 1.13 riastrad ATF_TP_FSAPPLY(read_fault);
274 1.1 pooka
275 1.1 pooka return atf_no_error();
276 1.1 pooka }
277