1*11be35a1SLionel Sambuc /* $NetBSD: t_io.c,v 1.11 2013/06/12 12:08:08 pooka Exp $ */ 2*11be35a1SLionel Sambuc 3*11be35a1SLionel Sambuc /*- 4*11be35a1SLionel Sambuc * Copyright (c) 2010 The NetBSD Foundation, Inc. 5*11be35a1SLionel Sambuc * All rights reserved. 6*11be35a1SLionel Sambuc * 7*11be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without 8*11be35a1SLionel Sambuc * modification, are permitted provided that the following conditions 9*11be35a1SLionel Sambuc * are met: 10*11be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 11*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer. 12*11be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 13*11be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 14*11be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution. 15*11be35a1SLionel Sambuc * 16*11be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17*11be35a1SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18*11be35a1SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*11be35a1SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20*11be35a1SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*11be35a1SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*11be35a1SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23*11be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24*11be35a1SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25*11be35a1SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26*11be35a1SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE. 27*11be35a1SLionel Sambuc */ 28*11be35a1SLionel Sambuc 29*11be35a1SLionel Sambuc #include <sys/stat.h> 30*11be35a1SLionel Sambuc #include <sys/statvfs.h> 31*11be35a1SLionel Sambuc 32*11be35a1SLionel Sambuc #include <atf-c.h> 33*11be35a1SLionel Sambuc #include <fcntl.h> 34*11be35a1SLionel Sambuc #include <libgen.h> 35*11be35a1SLionel Sambuc #include <stdlib.h> 36*11be35a1SLionel Sambuc #include <unistd.h> 37*11be35a1SLionel Sambuc 38*11be35a1SLionel Sambuc #include <rump/rump_syscalls.h> 39*11be35a1SLionel Sambuc #include <rump/rump.h> 40*11be35a1SLionel Sambuc 41*11be35a1SLionel Sambuc #include "../common/h_fsmacros.h" 42*11be35a1SLionel Sambuc #include "../../h_macros.h" 43*11be35a1SLionel Sambuc 44*11be35a1SLionel Sambuc #define TESTSTR "this is a string. collect enough and you'll have Em" 45*11be35a1SLionel Sambuc #define TESTSZ sizeof(TESTSTR) 46*11be35a1SLionel Sambuc 47*11be35a1SLionel Sambuc static void 48*11be35a1SLionel Sambuc holywrite(const atf_tc_t *tc, const char *mp) 49*11be35a1SLionel Sambuc { 50*11be35a1SLionel Sambuc char buf[1024]; 51*11be35a1SLionel Sambuc char *b2, *b3; 52*11be35a1SLionel Sambuc size_t therange = getpagesize()+1; 53*11be35a1SLionel Sambuc int fd; 54*11be35a1SLionel Sambuc 55*11be35a1SLionel Sambuc FSTEST_ENTER(); 56*11be35a1SLionel Sambuc 57*11be35a1SLionel Sambuc RL(fd = rump_sys_open("file", O_RDWR|O_CREAT|O_TRUNC, 0666)); 58*11be35a1SLionel Sambuc 59*11be35a1SLionel Sambuc memset(buf, 'A', sizeof(buf)); 60*11be35a1SLionel Sambuc RL(rump_sys_pwrite(fd, buf, 1, getpagesize())); 61*11be35a1SLionel Sambuc 62*11be35a1SLionel Sambuc memset(buf, 'B', sizeof(buf)); 63*11be35a1SLionel Sambuc RL(rump_sys_pwrite(fd, buf, 2, getpagesize()-1)); 64*11be35a1SLionel Sambuc 65*11be35a1SLionel Sambuc REQUIRE_LIBC(b2 = malloc(2 * getpagesize()), NULL); 66*11be35a1SLionel Sambuc REQUIRE_LIBC(b3 = malloc(2 * getpagesize()), NULL); 67*11be35a1SLionel Sambuc 68*11be35a1SLionel Sambuc RL(rump_sys_pread(fd, b2, therange, 0)); 69*11be35a1SLionel Sambuc 70*11be35a1SLionel Sambuc memset(b3, 0, therange); 71*11be35a1SLionel Sambuc memset(b3 + getpagesize() - 1, 'B', 2); 72*11be35a1SLionel Sambuc 73*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(memcmp(b2, b3, therange), 0); 74*11be35a1SLionel Sambuc 75*11be35a1SLionel Sambuc rump_sys_close(fd); 76*11be35a1SLionel Sambuc FSTEST_EXIT(); 77*11be35a1SLionel Sambuc } 78*11be35a1SLionel Sambuc 79*11be35a1SLionel Sambuc static void 80*11be35a1SLionel Sambuc extendbody(const atf_tc_t *tc, off_t seekcnt) 81*11be35a1SLionel Sambuc { 82*11be35a1SLionel Sambuc char buf[TESTSZ+1]; 83*11be35a1SLionel Sambuc struct stat sb; 84*11be35a1SLionel Sambuc int fd; 85*11be35a1SLionel Sambuc 86*11be35a1SLionel Sambuc FSTEST_ENTER(); 87*11be35a1SLionel Sambuc RL(fd = rump_sys_open("testfile", 88*11be35a1SLionel Sambuc O_CREAT | O_RDWR | (seekcnt ? O_APPEND : 0))); 89*11be35a1SLionel Sambuc RL(rump_sys_ftruncate(fd, seekcnt)); 90*11be35a1SLionel Sambuc RL(rump_sys_fstat(fd, &sb)); 91*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(sb.st_size, seekcnt); 92*11be35a1SLionel Sambuc 93*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_write(fd, TESTSTR, TESTSZ), TESTSZ); 94*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_pread(fd, buf, TESTSZ, seekcnt), TESTSZ); 95*11be35a1SLionel Sambuc ATF_REQUIRE_STREQ(buf, TESTSTR); 96*11be35a1SLionel Sambuc 97*11be35a1SLionel Sambuc RL(rump_sys_fstat(fd, &sb)); 98*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(sb.st_size, (off_t)TESTSZ + seekcnt); 99*11be35a1SLionel Sambuc RL(rump_sys_close(fd)); 100*11be35a1SLionel Sambuc FSTEST_EXIT(); 101*11be35a1SLionel Sambuc } 102*11be35a1SLionel Sambuc 103*11be35a1SLionel Sambuc static void 104*11be35a1SLionel Sambuc extendfile(const atf_tc_t *tc, const char *mp) 105*11be35a1SLionel Sambuc { 106*11be35a1SLionel Sambuc 107*11be35a1SLionel Sambuc extendbody(tc, 0); 108*11be35a1SLionel Sambuc } 109*11be35a1SLionel Sambuc 110*11be35a1SLionel Sambuc static void 111*11be35a1SLionel Sambuc extendfile_append(const atf_tc_t *tc, const char *mp) 112*11be35a1SLionel Sambuc { 113*11be35a1SLionel Sambuc 114*11be35a1SLionel Sambuc extendbody(tc, 37); 115*11be35a1SLionel Sambuc } 116*11be35a1SLionel Sambuc 117*11be35a1SLionel Sambuc static void 118*11be35a1SLionel Sambuc overwritebody(const atf_tc_t *tc, off_t count, bool dotrunc) 119*11be35a1SLionel Sambuc { 120*11be35a1SLionel Sambuc char *buf; 121*11be35a1SLionel Sambuc int fd; 122*11be35a1SLionel Sambuc 123*11be35a1SLionel Sambuc REQUIRE_LIBC(buf = malloc(count), NULL); 124*11be35a1SLionel Sambuc FSTEST_ENTER(); 125*11be35a1SLionel Sambuc RL(fd = rump_sys_open("testi", O_CREAT | O_RDWR, 0666)); 126*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_write(fd, buf, count), count); 127*11be35a1SLionel Sambuc RL(rump_sys_close(fd)); 128*11be35a1SLionel Sambuc 129*11be35a1SLionel Sambuc RL(fd = rump_sys_open("testi", O_RDWR)); 130*11be35a1SLionel Sambuc if (dotrunc) 131*11be35a1SLionel Sambuc RL(rump_sys_ftruncate(fd, 0)); 132*11be35a1SLionel Sambuc ATF_REQUIRE_EQ(rump_sys_write(fd, buf, count), count); 133*11be35a1SLionel Sambuc RL(rump_sys_close(fd)); 134*11be35a1SLionel Sambuc FSTEST_EXIT(); 135*11be35a1SLionel Sambuc } 136*11be35a1SLionel Sambuc 137*11be35a1SLionel Sambuc static void 138*11be35a1SLionel Sambuc overwrite512(const atf_tc_t *tc, const char *mp) 139*11be35a1SLionel Sambuc { 140*11be35a1SLionel Sambuc 141*11be35a1SLionel Sambuc overwritebody(tc, 512, false); 142*11be35a1SLionel Sambuc } 143*11be35a1SLionel Sambuc 144*11be35a1SLionel Sambuc static void 145*11be35a1SLionel Sambuc overwrite64k(const atf_tc_t *tc, const char *mp) 146*11be35a1SLionel Sambuc { 147*11be35a1SLionel Sambuc 148*11be35a1SLionel Sambuc overwritebody(tc, 1<<16, false); 149*11be35a1SLionel Sambuc } 150*11be35a1SLionel Sambuc 151*11be35a1SLionel Sambuc static void 152*11be35a1SLionel Sambuc overwrite_trunc(const atf_tc_t *tc, const char *mp) 153*11be35a1SLionel Sambuc { 154*11be35a1SLionel Sambuc 155*11be35a1SLionel Sambuc overwritebody(tc, 1<<16, true); 156*11be35a1SLionel Sambuc } 157*11be35a1SLionel Sambuc 158*11be35a1SLionel Sambuc static void 159*11be35a1SLionel Sambuc shrinkfile(const atf_tc_t *tc, const char *mp) 160*11be35a1SLionel Sambuc { 161*11be35a1SLionel Sambuc int fd; 162*11be35a1SLionel Sambuc 163*11be35a1SLionel Sambuc FSTEST_ENTER(); 164*11be35a1SLionel Sambuc RL(fd = rump_sys_open("file", O_RDWR|O_CREAT|O_TRUNC, 0666)); 165*11be35a1SLionel Sambuc RL(rump_sys_ftruncate(fd, 2)); 166*11be35a1SLionel Sambuc RL(rump_sys_ftruncate(fd, 1)); 167*11be35a1SLionel Sambuc rump_sys_close(fd); 168*11be35a1SLionel Sambuc FSTEST_EXIT(); 169*11be35a1SLionel Sambuc } 170*11be35a1SLionel Sambuc 171*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(holywrite, "create a sparse file and fill hole"); 172*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(extendfile, "check that extending a file works"); 173*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(extendfile_append, "check that extending a file works " 174*11be35a1SLionel Sambuc "with a append-only fd (PR kern/44307)"); 175*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(overwrite512, "write a 512 byte file twice"); 176*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(overwrite64k, "write a 64k byte file twice"); 177*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(overwrite_trunc, "write 64k + truncate + rewrite"); 178*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(shrinkfile, "shrink file"); 179*11be35a1SLionel Sambuc 180*11be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp) 181*11be35a1SLionel Sambuc { 182*11be35a1SLionel Sambuc 183*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(holywrite); 184*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(extendfile); 185*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(extendfile_append); 186*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(overwrite512); 187*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(overwrite64k); 188*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(overwrite_trunc); 189*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(shrinkfile); 190*11be35a1SLionel Sambuc 191*11be35a1SLionel Sambuc return atf_no_error(); 192*11be35a1SLionel Sambuc } 193