1 /* $NetBSD: t_io.c,v 1.16 2015/04/04 12:34:44 riastradh Exp $ */
4 * Copyright (c) 2010 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/statvfs.h>
38 #include <rump/rump_syscalls.h>
39 #include <rump/rump.h>
41 #include "../common/h_fsmacros.h"
42 #include "../../h_macros.h"
44 #define TESTSTR "this is a string. collect enough and you'll have Em"
45 #define TESTSZ sizeof(TESTSTR)
48 holywrite(const atf_tc_t
*tc
, const char *mp
)
52 size_t therange
= getpagesize()+1;
57 RL(fd
= rump_sys_open("file", O_RDWR
|O_CREAT
|O_TRUNC
, 0666));
59 memset(buf
, 'A', sizeof(buf
));
60 RL(rump_sys_pwrite(fd
, buf
, 1, getpagesize()));
62 memset(buf
, 'B', sizeof(buf
));
63 RL(rump_sys_pwrite(fd
, buf
, 2, getpagesize()-1));
65 REQUIRE_LIBC(b2
= malloc(2 * getpagesize()), NULL
);
66 REQUIRE_LIBC(b3
= malloc(2 * getpagesize()), NULL
);
68 RL(rump_sys_pread(fd
, b2
, therange
, 0));
70 memset(b3
, 0, therange
);
71 memset(b3
+ getpagesize() - 1, 'B', 2);
73 ATF_REQUIRE_EQ(memcmp(b2
, b3
, therange
), 0);
80 extendbody(const atf_tc_t
*tc
, off_t seekcnt
)
87 RL(fd
= rump_sys_open("testfile",
88 O_CREAT
| O_RDWR
| (seekcnt
? O_APPEND
: 0)));
89 RL(rump_sys_ftruncate(fd
, seekcnt
));
90 RL(rump_sys_fstat(fd
, &sb
));
91 ATF_REQUIRE_EQ(sb
.st_size
, seekcnt
);
93 ATF_REQUIRE_EQ(rump_sys_write(fd
, TESTSTR
, TESTSZ
), TESTSZ
);
94 ATF_REQUIRE_EQ(rump_sys_pread(fd
, buf
, TESTSZ
, seekcnt
), TESTSZ
);
95 ATF_REQUIRE_STREQ(buf
, TESTSTR
);
97 RL(rump_sys_fstat(fd
, &sb
));
98 ATF_REQUIRE_EQ(sb
.st_size
, (off_t
)TESTSZ
+ seekcnt
);
99 RL(rump_sys_close(fd
));
104 extendfile(const atf_tc_t
*tc
, const char *mp
)
111 extendfile_append(const atf_tc_t
*tc
, const char *mp
)
118 overwritebody(const atf_tc_t
*tc
, off_t count
, bool dotrunc
)
123 REQUIRE_LIBC(buf
= malloc(count
), NULL
);
125 RL(fd
= rump_sys_open("testi", O_CREAT
| O_RDWR
, 0666));
126 ATF_REQUIRE_EQ(rump_sys_write(fd
, buf
, count
), count
);
127 RL(rump_sys_close(fd
));
129 RL(fd
= rump_sys_open("testi", O_RDWR
));
131 RL(rump_sys_ftruncate(fd
, 0));
132 ATF_REQUIRE_EQ(rump_sys_write(fd
, buf
, count
), count
);
133 RL(rump_sys_close(fd
));
138 overwrite512(const atf_tc_t
*tc
, const char *mp
)
141 overwritebody(tc
, 512, false);
145 overwrite64k(const atf_tc_t
*tc
, const char *mp
)
148 overwritebody(tc
, 1<<16, false);
152 overwrite_trunc(const atf_tc_t
*tc
, const char *mp
)
155 overwritebody(tc
, 1<<16, true);
159 shrinkfile(const atf_tc_t
*tc
, const char *mp
)
164 RL(fd
= rump_sys_open("file", O_RDWR
|O_CREAT
|O_TRUNC
, 0666));
165 RL(rump_sys_ftruncate(fd
, 2));
166 RL(rump_sys_ftruncate(fd
, 1));
173 read_after_unlink(const atf_tc_t
*tc
, const char *mp
)
175 char buf
[TBSIZE
], buf2
[TBSIZE
];
180 /* create file and put some content into it */
181 RL(fd
= rump_sys_open("file", O_RDWR
|O_CREAT
, 0666));
182 memset(buf
, 'D', TBSIZE
);
183 ATF_REQUIRE_EQ(rump_sys_write(fd
, buf
, TBSIZE
), TBSIZE
);
186 /* flush buffers from UBC to file system */
187 ATF_REQUIRE_ERRNO(EBUSY
, rump_sys_unmount(mp
, 0) == -1);
189 RL(fd
= rump_sys_open("file", O_RDWR
));
190 RL(rump_sys_unlink("file"));
192 ATF_REQUIRE_EQ(rump_sys_read(fd
, buf2
, TBSIZE
), TBSIZE
);
193 ATF_REQUIRE_EQ(memcmp(buf
, buf2
, TBSIZE
), 0);
200 wrrd_after_unlink(const atf_tc_t
*tc
, const char *mp
)
208 RL(fd
= rump_sys_open("file", O_RDWR
|O_CREAT
, 0666));
209 RL(rump_sys_unlink("file"));
211 RL(rump_sys_pwrite(fd
, &value
, sizeof(value
), 654321));
214 * We can't easily invalidate the buffer since we hold a
215 * reference, but try to get them to flush anyway.
217 RL(rump_sys_fsync(fd
));
218 RL(rump_sys_pread(fd
, &v2
, sizeof(v2
), 654321));
221 ATF_REQUIRE_EQ(value
, v2
);
226 read_fault(const atf_tc_t
*tc
, const char *mp
)
232 RL(fd
= rump_sys_open("file", O_CREAT
| O_RDWR
, 0777));
233 ATF_REQUIRE_EQ(rump_sys_write(fd
, &ch
, 1), 1);
234 RL(rump_sys_close(fd
));
235 RL(fd
= rump_sys_open("file", O_RDONLY
| O_SYNC
| O_RSYNC
));
236 ATF_REQUIRE_ERRNO(EFAULT
, rump_sys_read(fd
, NULL
, 1) == -1);
237 RL(rump_sys_close(fd
));
241 ATF_TC_FSAPPLY(holywrite
, "create a sparse file and fill hole");
242 ATF_TC_FSAPPLY(extendfile
, "check that extending a file works");
243 ATF_TC_FSAPPLY(extendfile_append
, "check that extending a file works "
244 "with a append-only fd (PR kern/44307)");
245 ATF_TC_FSAPPLY(overwrite512
, "write a 512 byte file twice");
246 ATF_TC_FSAPPLY(overwrite64k
, "write a 64k byte file twice");
247 ATF_TC_FSAPPLY(overwrite_trunc
, "write 64k + truncate + rewrite");
248 ATF_TC_FSAPPLY(shrinkfile
, "shrink file");
249 ATF_TC_FSAPPLY(read_after_unlink
, "contents can be read off disk after unlink");
250 ATF_TC_FSAPPLY(wrrd_after_unlink
, "file can be written and read after unlink");
251 ATF_TC_FSAPPLY(read_fault
, "read at bad address must return EFAULT");
256 ATF_TP_FSAPPLY(holywrite
);
257 ATF_TP_FSAPPLY(extendfile
);
258 ATF_TP_FSAPPLY(extendfile_append
);
259 ATF_TP_FSAPPLY(overwrite512
);
260 ATF_TP_FSAPPLY(overwrite64k
);
261 ATF_TP_FSAPPLY(overwrite_trunc
);
262 ATF_TP_FSAPPLY(shrinkfile
);
263 ATF_TP_FSAPPLY(read_after_unlink
);
264 ATF_TP_FSAPPLY(wrrd_after_unlink
);
265 ATF_TP_FSAPPLY(read_fault
);
267 return atf_no_error();