Message ID | 20191011214120.GI13097@magnolia (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] generic: check reflink multiple mmap write | expand |
On Fri, Oct 11, 2019 at 02:41:20PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > Add a test to make sure that we can handle multiple memory mappings to a > physical storage extent shared by multiple files, and that we can handle > the copy on write operation without error. Make sure we can also handle > mappings at different offsets in the page cache. > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > --- > v2: test at different offsets > --- > src/Makefile | 2 - > src/mmap-write-concurrent.c | 155 +++++++++++++++++++++++++++++++++++++++++++ I added an entry in .gitignore file. > tests/generic/945 | 104 +++++++++++++++++++++++++++++ > tests/generic/945.out | 31 +++++++++ > tests/generic/group | 1 > 5 files changed, 292 insertions(+), 1 deletion(-) > create mode 100644 src/mmap-write-concurrent.c > create mode 100755 tests/generic/945 > create mode 100644 tests/generic/945.out > > diff --git a/src/Makefile b/src/Makefile > index ef7cfa63..5bc33e77 100644 > --- a/src/Makefile > +++ b/src/Makefile > @@ -16,7 +16,7 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \ > holetest t_truncate_self t_mmap_dio af_unix t_mmap_stale_pmd \ > t_mmap_cow_race t_mmap_fallocate fsync-err t_mmap_write_ro \ > t_ext4_dax_journal_corruption t_ext4_dax_inline_corruption \ > - t_ofd_locks t_locks_execve t_mmap_collision > + t_ofd_locks t_locks_execve t_mmap_collision mmap-write-concurrent > > 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/mmap-write-concurrent.c b/src/mmap-write-concurrent.c > new file mode 100644 > index 00000000..38364de8 > --- /dev/null > +++ b/src/mmap-write-concurrent.c > @@ -0,0 +1,155 @@ > +// SPDX-License-Identifier: GPL-2.0-or-newer > +/* > + * Copyright (c) 2019 Oracle. > + * All Rights Reserved. > + * > + * Create writable mappings to multiple files and write them all to test > + * concurrent mmap writes to the same shared blocks. > + */ > +#include <sys/mman.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include <stdio.h> > +#include <errno.h> > +#include <stdlib.h> > +#include <string.h> > + > +struct file_info { > + char *mapping; > + off_t file_offset; > + off_t file_length; > + int fd; > +}; > + > +int > +main( > + int argc, > + char *argv[]) > +{ > + struct file_info *fi; > + size_t length; > + char *endptr; > + unsigned int nr_files; > + unsigned int i; > + char *buf; > + int ret; > + > + if (argc < 4) { > + printf("Usage: %s len offset file [offset file]...\n", argv[0]); > + return 1; > + } > + > + /* Parse mwrite length. */ > + errno = 0; > + length = strtoul(argv[1], &endptr, 0); > + if (errno) { > + perror(argv[1]); > + return 1; > + } > + if (*endptr != '\0') { > + fprintf(stderr, "%s: not a proper file length?\n", argv[2]); > + return 1; > + } > + > + /* Allocate file info */ > + nr_files = (argc - 2) / 2; > + > + fi = calloc(nr_files, sizeof(struct file_info)); > + if (!fi) { > + perror("calloc file info"); > + return 1; > + } > + > + buf = malloc(length); > + if (!buf) { > + perror("malloc buf"); > + return 1; > + } > + > + for (i = 0; i < nr_files; i++) { > + struct stat statbuf; > + char *offset = argv[((i + 1) * 2)]; > + char *fname = argv[((i + 1) * 2) + 1]; > + > + /* Open file, create mapping for the range we want. */ > + fi[i].fd = open(fname, O_RDWR); > + if (fi[i].fd < 0) { > + perror(fname); > + return 1; > + } > + > + /* Parse mwrite offset */ > + errno = 0; > + fi[i].file_offset = strtoul(offset, &endptr, 0); > + if (errno) { > + perror(argv[1]); > + return 1; > + } > + > + /* Remember file size */ > + ret = fstat(fi[i].fd, &statbuf); > + if (ret) { > + perror(fname); > + return 1; > + } > + fi[i].file_length = statbuf.st_size; > + > + if (fi[i].file_offset + length > fi[i].file_length) { > + fprintf(stderr, "%s: file must be %llu bytes\n", > + fname, > + (unsigned long long)fi[i].file_offset + length); > + return 1; > + } > + > + /* Create the mapping */ > + fi[i].mapping = mmap(NULL, fi[i].file_length, > + PROT_READ | PROT_WRITE, MAP_SHARED, > + fi[i].fd, 0); > + if (fi[i].mapping == MAP_FAILED) { > + perror(fname); > + return 1; > + } > + > + /* > + * Make sure the mapping for region we're going to write is > + * already populated in the page cache. > + */ > + memcpy(buf, fi[i].mapping + fi[i].file_offset, length); > + } > + > + /* Dirty the same region in each file to test COW. */ > + for (i = 0; i < nr_files; i++) { > + memset(buf, 0x62 + i, length); > + memcpy(fi[i].mapping + fi[i].file_offset, buf, length); > + } > + for (i = 0; i < nr_files; i++) { > + ret = msync(fi[i].mapping, fi[i].file_offset + length, MS_SYNC); > + if (ret) { > + perror("msync"); > + return 1; > + } > + } > + > + /* Close everything. */ > + for (i = 0; i < nr_files; i++) { > + ret = munmap(fi[i].mapping, fi[i].file_length); > + if (ret) { > + perror("munmap"); > + return 1; > + } > + > + ret = close(fi[i].fd); > + if (ret) { > + perror("close"); > + return 1; > + } > + } > + > + /* Free everything. */ > + free(buf); > + free(fi); > + > + return 0; > +} > diff --git a/tests/generic/945 b/tests/generic/945 > new file mode 100755 > index 00000000..38b5883c > --- /dev/null > +++ b/tests/generic/945 > @@ -0,0 +1,104 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0-or-newer > +# Copyright (c) 2019, Oracle and/or its affiliates. All Rights Reserved. > +# > +# FS QA Test No. 945 > +# > +# Make sure that we can handle multiple mmap writers to the same file. > + > +seq=`basename $0` > +seqres=$RESULT_DIR/$seq > +echo "QA output created by $seq" > + > +here=`pwd` > +tmp=/tmp/$$ > +status=1 # failure is the default! > +trap "_cleanup; exit \$status" 0 1 2 3 15 > + > +_cleanup() > +{ > + cd / > + rm -rf $tmp.* $testdir > +} > + > +# get standard environment, filters and checks > +. ./common/rc > +. ./common/filter > +. ./common/reflink > + > +# real QA test starts here > +_supported_os Linux > +_supported_fs generic > +_require_command "$FILEFRAG_PROG" filefrag Also added _require_test_program "mmap-write-concurrent" > +_require_test_reflink > +_require_cp_reflink > + > +rm -f $seqres.full > + > +compare() { > + for i in $(seq 1 8); do > + md5sum $testdir/file$i | _filter_test_dir > + echo $testdir/file$i >> $seqres.full > + od -tx1 -Ad -c $testdir/file$i >> $seqres.full > + done > +} > + > +testdir=$TEST_DIR/test-$seq > +rm -rf $testdir > +mkdir $testdir > + > +echo "Create the original files" > +blksz=65536 > +filesz=$((blksz * 4)) > +_pwrite_byte 0x61 0 $filesz $testdir/file1 >> $seqres.full > +_cp_reflink $testdir/file1 $testdir/file2 >> $seqres.full > +_cp_reflink $testdir/file1 $testdir/file3 >> $seqres.full > +_cp_reflink $testdir/file1 $testdir/file4 >> $seqres.full > +_reflink_range $testdir/file1 0 $testdir/file5 $blksz $filesz >> $seqres.full > +_reflink_range $testdir/file1 0 $testdir/file6 $((blksz * 2)) $filesz >> $seqres.full > +_reflink_range $testdir/file1 0 $testdir/file7 $((blksz * 3)) $filesz >> $seqres.full > +_reflink_range $testdir/file1 0 $testdir/file8 $((blksz * 4)) $filesz >> $seqres.full > +_test_cycle_mount > + > +echo "Compare files before cow" | tee -a $seqres.full > +compare > + > +echo "mwrite all copies" | tee -a $seqres.full > +off=$(( (filesz / 2) - 168 )) > +len=337 > +./src/mmap-write-concurrent $len \ And used "$here/src/mmap-write-concurrent .." here. Thanks, Eryu > + $off $testdir/file1 \ > + $off $testdir/file2 \ > + $off $testdir/file3 \ > + $off $testdir/file4 \ > + $((off + blksz)) $testdir/file5 \ > + $((off + (blksz * 2))) $testdir/file6 \ > + $((off + (blksz * 3))) $testdir/file7 \ > + $((off + (blksz * 4))) $testdir/file8 \ > + 168 $testdir/file1 \ > + $((blksz - 168)) $testdir/file2 \ > + $((filesz - 777)) $testdir/file3 \ > + $(((blksz * 3) - 168)) $testdir/file4 \ > + > + > +echo "Compare files before remount" | tee -a $seqres.full > +compare > +_test_cycle_mount > + > +echo "Compare files after remount" | tee -a $seqres.full > +compare > + > +echo "Check for non-shared extents" | tee -a $seqres.full > +$FILEFRAG_PROG -v $testdir/file1 $testdir/file2 $testdir/file3 $testdir/file4 \ > + $testdir/file5 $testdir/file6 $testdir/file7 $testdir/file8 \ > + | grep '^[[:space:]]*[0-9]*:' > $testdir/fiemap > +cat $testdir/fiemap >> $seqres.full > +grep -q 'shared' $testdir/fiemap || \ > + echo "Expected to find shared extents" > + > +grep -q -v 'shared' $testdir/fiemap || \ > + echo "Expected to find non-shared extents" > + > +# success, all done > +status=0 > +exit > diff --git a/tests/generic/945.out b/tests/generic/945.out > new file mode 100644 > index 00000000..ad1e21ff > --- /dev/null > +++ b/tests/generic/945.out > @@ -0,0 +1,31 @@ > +QA output created by 945 > +Create the original files > +Compare files before cow > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file1 > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file2 > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file3 > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file4 > +74e6b9b1a03fdf09293c089b002800f8 TEST_DIR/test-945/file5 > +c14f20b97155e3fc11a17532d02ad9df TEST_DIR/test-945/file6 > +22eb46e0f4a3742c8d86346845b7bc80 TEST_DIR/test-945/file7 > +4d292f06cec9d3f1bece4822cd5ef532 TEST_DIR/test-945/file8 > +mwrite all copies > +Compare files before remount > +c1b46135a2620ae6da21bbfd4cbb3cba TEST_DIR/test-945/file1 > +16f0bc0f97c42d2ad903c519095b8126 TEST_DIR/test-945/file2 > +eb71e3135ca2abf33bb9081e2b49a876 TEST_DIR/test-945/file3 > +2678dfcb77bed4dc29e19836bef82e5b TEST_DIR/test-945/file4 > +2802d75dbee4f29d62124aa7b473edca TEST_DIR/test-945/file5 > +acd58cf3d33ef905e26800a0e049223c TEST_DIR/test-945/file6 > +1b68d203e5a1c1b45a9510bedcd1e126 TEST_DIR/test-945/file7 > +9479709b697ced2e3a57c17bc1b97373 TEST_DIR/test-945/file8 > +Compare files after remount > +c1b46135a2620ae6da21bbfd4cbb3cba TEST_DIR/test-945/file1 > +16f0bc0f97c42d2ad903c519095b8126 TEST_DIR/test-945/file2 > +eb71e3135ca2abf33bb9081e2b49a876 TEST_DIR/test-945/file3 > +2678dfcb77bed4dc29e19836bef82e5b TEST_DIR/test-945/file4 > +2802d75dbee4f29d62124aa7b473edca TEST_DIR/test-945/file5 > +acd58cf3d33ef905e26800a0e049223c TEST_DIR/test-945/file6 > +1b68d203e5a1c1b45a9510bedcd1e126 TEST_DIR/test-945/file7 > +9479709b697ced2e3a57c17bc1b97373 TEST_DIR/test-945/file8 > +Check for non-shared extents > diff --git a/tests/generic/group b/tests/generic/group > index 4584667f..f77c5b21 100644 > --- a/tests/generic/group > +++ b/tests/generic/group > @@ -576,3 +576,4 @@ > 715 dangerous_norepair > 716 dangerous_norepair > 720 dangerous_norepair > +945 auto quick rw clone
On Sun, Oct 13, 2019 at 08:11:37PM +0800, Eryu Guan wrote: > On Fri, Oct 11, 2019 at 02:41:20PM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > Add a test to make sure that we can handle multiple memory mappings to a > > physical storage extent shared by multiple files, and that we can handle > > the copy on write operation without error. Make sure we can also handle > > mappings at different offsets in the page cache. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> > > --- > > v2: test at different offsets > > --- > > src/Makefile | 2 - > > src/mmap-write-concurrent.c | 155 +++++++++++++++++++++++++++++++++++++++++++ > > I added an entry in .gitignore file. Thanks! <snip> > > + > > +# real QA test starts here > > +_supported_os Linux > > +_supported_fs generic > > +_require_command "$FILEFRAG_PROG" filefrag > > Also added > > _require_test_program "mmap-write-concurrent" > > > +echo "mwrite all copies" | tee -a $seqres.full > > +off=$(( (filesz / 2) - 168 )) > > +len=337 > > +./src/mmap-write-concurrent $len \ > > And used "$here/src/mmap-write-concurrent .." here. Old habits die hard, I guess. :( Thanks for fixing those up on commit... --D > Thanks, > Eryu > > > + $off $testdir/file1 \ > > + $off $testdir/file2 \ > > + $off $testdir/file3 \ > > + $off $testdir/file4 \ > > + $((off + blksz)) $testdir/file5 \ > > + $((off + (blksz * 2))) $testdir/file6 \ > > + $((off + (blksz * 3))) $testdir/file7 \ > > + $((off + (blksz * 4))) $testdir/file8 \ > > + 168 $testdir/file1 \ > > + $((blksz - 168)) $testdir/file2 \ > > + $((filesz - 777)) $testdir/file3 \ > > + $(((blksz * 3) - 168)) $testdir/file4 \ > > + > > + > > +echo "Compare files before remount" | tee -a $seqres.full > > +compare > > +_test_cycle_mount > > + > > +echo "Compare files after remount" | tee -a $seqres.full > > +compare > > + > > +echo "Check for non-shared extents" | tee -a $seqres.full > > +$FILEFRAG_PROG -v $testdir/file1 $testdir/file2 $testdir/file3 $testdir/file4 \ > > + $testdir/file5 $testdir/file6 $testdir/file7 $testdir/file8 \ > > + | grep '^[[:space:]]*[0-9]*:' > $testdir/fiemap > > +cat $testdir/fiemap >> $seqres.full > > +grep -q 'shared' $testdir/fiemap || \ > > + echo "Expected to find shared extents" > > + > > +grep -q -v 'shared' $testdir/fiemap || \ > > + echo "Expected to find non-shared extents" > > + > > +# success, all done > > +status=0 > > +exit > > diff --git a/tests/generic/945.out b/tests/generic/945.out > > new file mode 100644 > > index 00000000..ad1e21ff > > --- /dev/null > > +++ b/tests/generic/945.out > > @@ -0,0 +1,31 @@ > > +QA output created by 945 > > +Create the original files > > +Compare files before cow > > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file1 > > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file2 > > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file3 > > +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file4 > > +74e6b9b1a03fdf09293c089b002800f8 TEST_DIR/test-945/file5 > > +c14f20b97155e3fc11a17532d02ad9df TEST_DIR/test-945/file6 > > +22eb46e0f4a3742c8d86346845b7bc80 TEST_DIR/test-945/file7 > > +4d292f06cec9d3f1bece4822cd5ef532 TEST_DIR/test-945/file8 > > +mwrite all copies > > +Compare files before remount > > +c1b46135a2620ae6da21bbfd4cbb3cba TEST_DIR/test-945/file1 > > +16f0bc0f97c42d2ad903c519095b8126 TEST_DIR/test-945/file2 > > +eb71e3135ca2abf33bb9081e2b49a876 TEST_DIR/test-945/file3 > > +2678dfcb77bed4dc29e19836bef82e5b TEST_DIR/test-945/file4 > > +2802d75dbee4f29d62124aa7b473edca TEST_DIR/test-945/file5 > > +acd58cf3d33ef905e26800a0e049223c TEST_DIR/test-945/file6 > > +1b68d203e5a1c1b45a9510bedcd1e126 TEST_DIR/test-945/file7 > > +9479709b697ced2e3a57c17bc1b97373 TEST_DIR/test-945/file8 > > +Compare files after remount > > +c1b46135a2620ae6da21bbfd4cbb3cba TEST_DIR/test-945/file1 > > +16f0bc0f97c42d2ad903c519095b8126 TEST_DIR/test-945/file2 > > +eb71e3135ca2abf33bb9081e2b49a876 TEST_DIR/test-945/file3 > > +2678dfcb77bed4dc29e19836bef82e5b TEST_DIR/test-945/file4 > > +2802d75dbee4f29d62124aa7b473edca TEST_DIR/test-945/file5 > > +acd58cf3d33ef905e26800a0e049223c TEST_DIR/test-945/file6 > > +1b68d203e5a1c1b45a9510bedcd1e126 TEST_DIR/test-945/file7 > > +9479709b697ced2e3a57c17bc1b97373 TEST_DIR/test-945/file8 > > +Check for non-shared extents > > diff --git a/tests/generic/group b/tests/generic/group > > index 4584667f..f77c5b21 100644 > > --- a/tests/generic/group > > +++ b/tests/generic/group > > @@ -576,3 +576,4 @@ > > 715 dangerous_norepair > > 716 dangerous_norepair > > 720 dangerous_norepair > > +945 auto quick rw clone
diff --git a/src/Makefile b/src/Makefile index ef7cfa63..5bc33e77 100644 --- a/src/Makefile +++ b/src/Makefile @@ -16,7 +16,7 @@ TARGETS = dirstress fill fill2 getpagesize holes lstat64 \ holetest t_truncate_self t_mmap_dio af_unix t_mmap_stale_pmd \ t_mmap_cow_race t_mmap_fallocate fsync-err t_mmap_write_ro \ t_ext4_dax_journal_corruption t_ext4_dax_inline_corruption \ - t_ofd_locks t_locks_execve t_mmap_collision + t_ofd_locks t_locks_execve t_mmap_collision mmap-write-concurrent 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/mmap-write-concurrent.c b/src/mmap-write-concurrent.c new file mode 100644 index 00000000..38364de8 --- /dev/null +++ b/src/mmap-write-concurrent.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0-or-newer +/* + * Copyright (c) 2019 Oracle. + * All Rights Reserved. + * + * Create writable mappings to multiple files and write them all to test + * concurrent mmap writes to the same shared blocks. + */ +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +struct file_info { + char *mapping; + off_t file_offset; + off_t file_length; + int fd; +}; + +int +main( + int argc, + char *argv[]) +{ + struct file_info *fi; + size_t length; + char *endptr; + unsigned int nr_files; + unsigned int i; + char *buf; + int ret; + + if (argc < 4) { + printf("Usage: %s len offset file [offset file]...\n", argv[0]); + return 1; + } + + /* Parse mwrite length. */ + errno = 0; + length = strtoul(argv[1], &endptr, 0); + if (errno) { + perror(argv[1]); + return 1; + } + if (*endptr != '\0') { + fprintf(stderr, "%s: not a proper file length?\n", argv[2]); + return 1; + } + + /* Allocate file info */ + nr_files = (argc - 2) / 2; + + fi = calloc(nr_files, sizeof(struct file_info)); + if (!fi) { + perror("calloc file info"); + return 1; + } + + buf = malloc(length); + if (!buf) { + perror("malloc buf"); + return 1; + } + + for (i = 0; i < nr_files; i++) { + struct stat statbuf; + char *offset = argv[((i + 1) * 2)]; + char *fname = argv[((i + 1) * 2) + 1]; + + /* Open file, create mapping for the range we want. */ + fi[i].fd = open(fname, O_RDWR); + if (fi[i].fd < 0) { + perror(fname); + return 1; + } + + /* Parse mwrite offset */ + errno = 0; + fi[i].file_offset = strtoul(offset, &endptr, 0); + if (errno) { + perror(argv[1]); + return 1; + } + + /* Remember file size */ + ret = fstat(fi[i].fd, &statbuf); + if (ret) { + perror(fname); + return 1; + } + fi[i].file_length = statbuf.st_size; + + if (fi[i].file_offset + length > fi[i].file_length) { + fprintf(stderr, "%s: file must be %llu bytes\n", + fname, + (unsigned long long)fi[i].file_offset + length); + return 1; + } + + /* Create the mapping */ + fi[i].mapping = mmap(NULL, fi[i].file_length, + PROT_READ | PROT_WRITE, MAP_SHARED, + fi[i].fd, 0); + if (fi[i].mapping == MAP_FAILED) { + perror(fname); + return 1; + } + + /* + * Make sure the mapping for region we're going to write is + * already populated in the page cache. + */ + memcpy(buf, fi[i].mapping + fi[i].file_offset, length); + } + + /* Dirty the same region in each file to test COW. */ + for (i = 0; i < nr_files; i++) { + memset(buf, 0x62 + i, length); + memcpy(fi[i].mapping + fi[i].file_offset, buf, length); + } + for (i = 0; i < nr_files; i++) { + ret = msync(fi[i].mapping, fi[i].file_offset + length, MS_SYNC); + if (ret) { + perror("msync"); + return 1; + } + } + + /* Close everything. */ + for (i = 0; i < nr_files; i++) { + ret = munmap(fi[i].mapping, fi[i].file_length); + if (ret) { + perror("munmap"); + return 1; + } + + ret = close(fi[i].fd); + if (ret) { + perror("close"); + return 1; + } + } + + /* Free everything. */ + free(buf); + free(fi); + + return 0; +} diff --git a/tests/generic/945 b/tests/generic/945 new file mode 100755 index 00000000..38b5883c --- /dev/null +++ b/tests/generic/945 @@ -0,0 +1,104 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-newer +# Copyright (c) 2019, Oracle and/or its affiliates. All Rights Reserved. +# +# FS QA Test No. 945 +# +# Make sure that we can handle multiple mmap writers to the same file. + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $testdir +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs generic +_require_command "$FILEFRAG_PROG" filefrag +_require_test_reflink +_require_cp_reflink + +rm -f $seqres.full + +compare() { + for i in $(seq 1 8); do + md5sum $testdir/file$i | _filter_test_dir + echo $testdir/file$i >> $seqres.full + od -tx1 -Ad -c $testdir/file$i >> $seqres.full + done +} + +testdir=$TEST_DIR/test-$seq +rm -rf $testdir +mkdir $testdir + +echo "Create the original files" +blksz=65536 +filesz=$((blksz * 4)) +_pwrite_byte 0x61 0 $filesz $testdir/file1 >> $seqres.full +_cp_reflink $testdir/file1 $testdir/file2 >> $seqres.full +_cp_reflink $testdir/file1 $testdir/file3 >> $seqres.full +_cp_reflink $testdir/file1 $testdir/file4 >> $seqres.full +_reflink_range $testdir/file1 0 $testdir/file5 $blksz $filesz >> $seqres.full +_reflink_range $testdir/file1 0 $testdir/file6 $((blksz * 2)) $filesz >> $seqres.full +_reflink_range $testdir/file1 0 $testdir/file7 $((blksz * 3)) $filesz >> $seqres.full +_reflink_range $testdir/file1 0 $testdir/file8 $((blksz * 4)) $filesz >> $seqres.full +_test_cycle_mount + +echo "Compare files before cow" | tee -a $seqres.full +compare + +echo "mwrite all copies" | tee -a $seqres.full +off=$(( (filesz / 2) - 168 )) +len=337 +./src/mmap-write-concurrent $len \ + $off $testdir/file1 \ + $off $testdir/file2 \ + $off $testdir/file3 \ + $off $testdir/file4 \ + $((off + blksz)) $testdir/file5 \ + $((off + (blksz * 2))) $testdir/file6 \ + $((off + (blksz * 3))) $testdir/file7 \ + $((off + (blksz * 4))) $testdir/file8 \ + 168 $testdir/file1 \ + $((blksz - 168)) $testdir/file2 \ + $((filesz - 777)) $testdir/file3 \ + $(((blksz * 3) - 168)) $testdir/file4 \ + + +echo "Compare files before remount" | tee -a $seqres.full +compare +_test_cycle_mount + +echo "Compare files after remount" | tee -a $seqres.full +compare + +echo "Check for non-shared extents" | tee -a $seqres.full +$FILEFRAG_PROG -v $testdir/file1 $testdir/file2 $testdir/file3 $testdir/file4 \ + $testdir/file5 $testdir/file6 $testdir/file7 $testdir/file8 \ + | grep '^[[:space:]]*[0-9]*:' > $testdir/fiemap +cat $testdir/fiemap >> $seqres.full +grep -q 'shared' $testdir/fiemap || \ + echo "Expected to find shared extents" + +grep -q -v 'shared' $testdir/fiemap || \ + echo "Expected to find non-shared extents" + +# success, all done +status=0 +exit diff --git a/tests/generic/945.out b/tests/generic/945.out new file mode 100644 index 00000000..ad1e21ff --- /dev/null +++ b/tests/generic/945.out @@ -0,0 +1,31 @@ +QA output created by 945 +Create the original files +Compare files before cow +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file1 +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file2 +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file3 +c946b71bb69c07daf25470742c967e7c TEST_DIR/test-945/file4 +74e6b9b1a03fdf09293c089b002800f8 TEST_DIR/test-945/file5 +c14f20b97155e3fc11a17532d02ad9df TEST_DIR/test-945/file6 +22eb46e0f4a3742c8d86346845b7bc80 TEST_DIR/test-945/file7 +4d292f06cec9d3f1bece4822cd5ef532 TEST_DIR/test-945/file8 +mwrite all copies +Compare files before remount +c1b46135a2620ae6da21bbfd4cbb3cba TEST_DIR/test-945/file1 +16f0bc0f97c42d2ad903c519095b8126 TEST_DIR/test-945/file2 +eb71e3135ca2abf33bb9081e2b49a876 TEST_DIR/test-945/file3 +2678dfcb77bed4dc29e19836bef82e5b TEST_DIR/test-945/file4 +2802d75dbee4f29d62124aa7b473edca TEST_DIR/test-945/file5 +acd58cf3d33ef905e26800a0e049223c TEST_DIR/test-945/file6 +1b68d203e5a1c1b45a9510bedcd1e126 TEST_DIR/test-945/file7 +9479709b697ced2e3a57c17bc1b97373 TEST_DIR/test-945/file8 +Compare files after remount +c1b46135a2620ae6da21bbfd4cbb3cba TEST_DIR/test-945/file1 +16f0bc0f97c42d2ad903c519095b8126 TEST_DIR/test-945/file2 +eb71e3135ca2abf33bb9081e2b49a876 TEST_DIR/test-945/file3 +2678dfcb77bed4dc29e19836bef82e5b TEST_DIR/test-945/file4 +2802d75dbee4f29d62124aa7b473edca TEST_DIR/test-945/file5 +acd58cf3d33ef905e26800a0e049223c TEST_DIR/test-945/file6 +1b68d203e5a1c1b45a9510bedcd1e126 TEST_DIR/test-945/file7 +9479709b697ced2e3a57c17bc1b97373 TEST_DIR/test-945/file8 +Check for non-shared extents diff --git a/tests/generic/group b/tests/generic/group index 4584667f..f77c5b21 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -576,3 +576,4 @@ 715 dangerous_norepair 716 dangerous_norepair 720 dangerous_norepair +945 auto quick rw clone