From: Christoph Hellwig Date: Fri, 19 Nov 2010 14:57:05 +0000 (+0100) Subject: xfstests: check block truncation after write failure X-Git-Tag: v1.1.0~111 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=7f71f3ac1731ba3ef7df829e8459fd90803b2c1e;p=xfstests-dev.git xfstests: check block truncation after write failure Extraced from https://bugzilla.kernel.org/show_bug.cgi?id=22452 "data corruption after mmap()ing a file and writev() some data to another file" Signed-off-by: Christoph Hellwig Reviewed-by: Eric Sandeen Reviewed-by: Dave Chinner --- diff --git a/246 b/246 new file mode 100644 index 00000000..faa5ccac --- /dev/null +++ b/246 @@ -0,0 +1,60 @@ +#! /bin/bash +# FS QA Test No. 246 +# +# Check that truncation after failed writes does not zero too much data. +# +# Based on a bug report and testcase from +# Marius Tolzmann +# +#----------------------------------------------------------------------- +# Copyright (c) 2010 Christoph Hellwig. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#----------------------------------------------------------------------- +# +# creator +owner=hch@lst.de + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# real QA test starts here +_supported_fs generic +_supported_os Linux + +file=$TEST_DIR/mmap-writev + +_cleanup() +{ + rm -rf $file + rm -rf $file.NEW +} + +trap "_cleanup ; exit \$status" 0 1 2 3 15 + +echo -n "cccccccccc" > $file +$here/src/t_mmap_writev $file $file.NEW +od -t x2 $file.NEW + +status=0 +exit $status diff --git a/246.out b/246.out new file mode 100644 index 00000000..e00e48ee --- /dev/null +++ b/246.out @@ -0,0 +1,4 @@ +QA output created by 246 +0000000 6161 6161 6161 6161 6161 6262 6262 6262 +0000020 6262 6262 6363 6363 6363 6363 6363 +0000036 diff --git a/group b/group index 1dcf4ee9..25f5ad63 100644 --- a/group +++ b/group @@ -359,3 +359,4 @@ deprecated 243 auto quick prealloc 244 auto quota quick 245 auto quick dir +246 auto quick rw diff --git a/src/Makefile b/src/Makefile index e878cff6..b827bd0a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,7 +10,8 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \ mmapcat append_reader append_writer dirperf metaperf \ devzero feature alloc fault fstest t_access_root \ godown resvtest writemod makeextents itrash rename \ - multi_open_unlink dmiperf unwritten_sync genhashnames t_holes + multi_open_unlink dmiperf unwritten_sync genhashnames t_holes \ + t_mmap_writev LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \ preallo_rw_pattern_writer ftrunc trunc fs_perms testx looptest \ diff --git a/src/t_mmap_writev.c b/src/t_mmap_writev.c new file mode 100644 index 00000000..e5ca08ab --- /dev/null +++ b/src/t_mmap_writev.c @@ -0,0 +1,70 @@ +/* + mmap() a file and writev() back to another file + - kernel bug #22452 testcase + + Copyright (C) 2010 + by D.Buczek - Max Planck Institute for Molecular Genetics Berlin + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + char *file = argv[1]; + char *new_file = argv[2]; + int fd; + int fd_new; + void *base; + + struct iovec iovec[3]= + { + { "aaaaaaaaaa" , 10 }, + { "bbbbbbbbbb" , 10 }, + { NULL , 10 } + }; + + int i; + + fd=open(file, O_RDONLY); + if (fd==-1) {perror("open");exit(1);} + + base = mmap(NULL,16384,PROT_READ,MAP_SHARED,fd,0); + if (base == (void *)-1) { perror("mmap");exit(1); } + + unlink(new_file); + + fd_new=open(new_file,O_RDWR|O_CREAT,0666); + if (fd_new==-1) {perror("creat");exit(1);} + + iovec[2].iov_base=(char *)base; + i=writev(fd_new,iovec,sizeof(iovec)/sizeof(*iovec)); + if (i==-1) {perror("writev");exit(1);} + + close(fd_new); + munmap(base,16384); + close(fd); + + return 0; +}