1 1.19 christos /* $NetBSD: t_io.c,v 1.19 2019/07/16 21:13:28 christos 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.17 christos #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.19 christos O_CREAT | O_RDWR | (seekcnt ? O_APPEND : 0), 0600)); 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 ATF_REQUIRE_ERRNO(EFAULT, rump_sys_read(fd, NULL, 1) == -1); 237 1.13 riastrad RL(rump_sys_close(fd)); 238 1.13 riastrad FSTEST_EXIT(); 239 1.13 riastrad } 240 1.13 riastrad 241 1.1 pooka ATF_TC_FSAPPLY(holywrite, "create a sparse file and fill hole"); 242 1.3 pooka ATF_TC_FSAPPLY(extendfile, "check that extending a file works"); 243 1.3 pooka ATF_TC_FSAPPLY(extendfile_append, "check that extending a file works " 244 1.9 jruoho "with a append-only fd (PR kern/44307)"); 245 1.7 pooka ATF_TC_FSAPPLY(overwrite512, "write a 512 byte file twice"); 246 1.7 pooka ATF_TC_FSAPPLY(overwrite64k, "write a 64k byte file twice"); 247 1.7 pooka ATF_TC_FSAPPLY(overwrite_trunc, "write 64k + truncate + rewrite"); 248 1.8 njoly ATF_TC_FSAPPLY(shrinkfile, "shrink file"); 249 1.12 pooka ATF_TC_FSAPPLY(read_after_unlink, "contents can be read off disk after unlink"); 250 1.12 pooka ATF_TC_FSAPPLY(wrrd_after_unlink, "file can be written and read after unlink"); 251 1.13 riastrad ATF_TC_FSAPPLY(read_fault, "read at bad address must return EFAULT"); 252 1.1 pooka 253 1.1 pooka ATF_TP_ADD_TCS(tp) 254 1.1 pooka { 255 1.1 pooka 256 1.1 pooka ATF_TP_FSAPPLY(holywrite); 257 1.3 pooka ATF_TP_FSAPPLY(extendfile); 258 1.3 pooka ATF_TP_FSAPPLY(extendfile_append); 259 1.7 pooka ATF_TP_FSAPPLY(overwrite512); 260 1.7 pooka ATF_TP_FSAPPLY(overwrite64k); 261 1.7 pooka ATF_TP_FSAPPLY(overwrite_trunc); 262 1.8 njoly ATF_TP_FSAPPLY(shrinkfile); 263 1.12 pooka ATF_TP_FSAPPLY(read_after_unlink); 264 1.12 pooka ATF_TP_FSAPPLY(wrrd_after_unlink); 265 1.13 riastrad ATF_TP_FSAPPLY(read_fault); 266 1.1 pooka 267 1.1 pooka return atf_no_error(); 268 1.1 pooka } 269