xfstests: introduce 280 for SEEK_DATA/SEEK_HOLE copy check
PATCH v2 2/2 xfstests: introduce 280 for SEEK_DATA/SEEK_HOLE copy check
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
--- 280 | 148 ++++++++++ 280.out | 1 + group | 1 + src/Makefile | 3 +- src/seek_copy_tester.c | 709 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 861 insertions(+), 1 deletions(-) create mode 100755 280 create mode 100644 280.out create mode 100644 src/seek_copy_tester.c
280 new file +148 -0
@@ -0,0 +1,148 @@ +#! /bin/bash +# FS QA Test No. 280 +# +# SEEK_DATA/SEEK_HOLE tester. +# Create a sparse file with a couple of holes and data extents. +# Simulates the copy process to verify SEEK_DATA/SEEK_HOLE stuff works +# as expected. +# +#----------------------------------------------------------------------- +# Copyright (c) 2011 Oracle Inc. 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 [email protected] + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# real QA test starts here +_supported_fs generic +_supported_os Linux Solaris + +src=$TEST_DIR/seek_copy_testfile +dest=$TEST_DIR/seek_copy_testfile.dest + +[ -x $here/src/seek_copy_tester ] || _notrun "seek_copy_tester not built" + +_cleanup() +{ + rm -f $src $dest +} + +# seek_copy_test_01() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 80991, write 4Kbytes, +# and then skip 195001 bytes for next write. +# this is intended to test data buffer lookup for DIRTY pages. +# verify results: +# 1. file size is identical. +# 2. perform cmp(1) to compare SRC and DEST file byte by byte. +test01() +{ + rm -f $src $dest + + $here/src/seek_copy_tester -P -O 0 -L 100m -s 80991 -k 195001 -l 4k $src $dest + + test $(stat --printf "%s" $src) = $(stat --printf "%s" $dest) || + echo "TEST01: file size check failed" >> $seq.out + + cmp $src $dest || + echo "TEST01: file bytes check failed" >> $seq.out +} + +# seek_copy_test_02() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 0, write 16Kbytes, +# and then skip 8Mbytes for next write. +# Try flushing DIRTY pages to WRITEBACK mode, this is intended to +# test data buffer lookup in WRITEBACK pages. +# verify results: +# 1. file size is identical. +# 2. perform cmp(1) to compare SRC and DEST file byte by byte. +test02() +{ + rm -rf $src $dest + + $here/src/seek_copy_tester -S -P -O 0 -L 100m -s 0 -k 8m -l 16k $src $dest + + test $(stat --printf "%s" $src) = $(stat --printf "%s" $dest) || + echo "TEST02: file size check failed" >> $seq.out + + cmp $src $dest || + echo "TEST02: file bytes check failed" >>$seq.out +} + +# seek_copy_test_03 +# create a 100Mytes sparse file. +# the first data extent offset start from 512, write 4Kbytes, +# and then skip 1Mbytes for next write. +# don't make holes at the end of file. +# verify results: +# 1. file size is identical. +# 2. perform cmp(1) to compare SRC and DEST file byte by byte. +test03() +{ + rm -f $src $dest + + $here/src/seek_copy_tester -M 100m -s 512 -k 1m -l 4k $src $dest + + test $(stat --printf "%s" $src) = $(stat --printf "%s" $dest) || + echo "FAIL_TEST03: file size no equal" >> $seq.out + + cmp $src $dest || + echo "FAIL_TEST03: file compare failed" >>$seq.out +} + +# seek_copy_test_04 +# create a 1Gbytes sparse file. +# the first data extent offset start from 512, write 4Kbytes, +# and then skip 1Mbytes for next write. +# make holes at the end of file. +# verify results: +# 1. file size is identical. +# 2. perform cmp(1) to compare SRC and DEST file byte by byte. +test04() +{ + rm -f $src $dest + + $here/src/seek_copy_tester -M 1g -s 512 -k 1m -l 4k -E $src $dest + + test $(stat --printf "%s" $src) = $(stat --printf "%s" $dest) || + echo "FAIL_TEST04: file size no equal" >> $seq.out + cmp $src $dest || + echo "FAIL_TEST04: file compare failed" >>$seq.out +} + +echo "QA output created by $seq" >> $seq.out +test01 +test02 +test03 +test04 + +status=0 +exit
280.out new file +1 -0
@@ -0,0 +1 @@ +QA output created by 280
group +1 -0
@@ -390,3 +390,4 @@ deprecated 274 auto rw 275 auto rw 279 auto rw +280 auto rw
src/Makefile +2 -1
@@ -17,7 +17,8 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \ preallo_rw_pattern_writer ftrunc trunc fs_perms testx looptest \ locktest unwritten_mmap bulkstat_unlink_test t_stripealign \ bulkstat_unlink_test_modified t_dir_offset t_futimens t_immutable \ - stale_handle pwrite_mmap_blocked fstrim t_dir_offset2 seek_sanity_tester + stale_handle pwrite_mmap_blocked fstrim t_dir_offset2 seek_sanity_tester \ + seek_copy_tester SUBDIRS =
src/seek_copy_tester.c new file +709 -0
709 lines not on this page · raw message
Signature · 6 lines
1.7.9 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 14 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu<[email protected]>---
src/seek_copy_tester.c new file +1
-0+static size_t
src/seek_copy_tester.c line 111
Quoted 10 lines
src/seek_copy_tester.c new file +10
-0+full_write(int fd, const void *buf, size_t count) +{ + size_t total = 0; +const char *ptr = (const char *) buf; + +while (count>0 ) { +ssize_t n =write (fd, ptr, count); +if (n<0 ) { +if (errno ==EINTR ) +continue ;
Wouldn't you want to stop the write loop if interrupted?
src/seek_copy_tester.c line 117
Quoted 6 lines
src/seek_copy_tester.c new file +6
-0+error ("full_write() failed as %s" ,strerror (errno)); +break ; + } + +if (n ==0 ) { +error ("full_write() ZERO bytes transferred" );
You can tell them how many (total) bytes were written before the error. Same in full_pwrite()
Quoted 4 lines
src/seek_copy_tester.c new file +4
-0+create_data_and_holes(int fd, size_t nr_total_bytes, off_t start_offset, + uint64_t nr_skip_bytes, uint64_t nr_data_bytes, + int wrote_hole_at_eof) +{
src/seek_copy_tester.c
Quoted 10 lines
src/seek_copy_tester.c new file +10
-0+int ret =0 ; +off_t total = nr_total_bytes; +off_t data_len = nr_data_bytes; +off_t off = start_offset; +char buf[BUF_SIZE ]; + +memset (buf,'A' ,sizeof (buf)); + + total -= start_offset; +while (total>0 ) {
+ data_len = nr_data_bytes; /* see below */
src/seek_copy_tester.c line 242
Quoted 2 lines
src/seek_copy_tester.c new file +2
-0+ do { + size_t nr_write = MIN(total, BUF_SIZE);
There are 2 dependencies:
1) The last nr_data_bytes does not exceed total (outer loop)
2) The remaining data size (data_len) could be less than BUF_SIZE (if data_len is not a multiple of BUF_SIZE for example).
src/seek_copy_tester.c
Quoted 9 lines
src/seek_copy_tester.c new file +9
-0+if (full_pwrite (fd, buf, nr_write, off) != nr_write) { +error ("full_pwrite() failed as %s" ,strerror (errno)); + ret =-1 ; + goto out; + } + + off += nr_write; + data_len -= nr_write; + }while (data_len>0 );
data_len is <= 0 so the inner loop will execute only once if you have more than one chunk of data.
Quoted 14 lines
src/seek_copy_tester.c new file +14
-0+ + off += (nr_skip_bytes + nr_data_bytes); + total -= off; + } + +if (off< nr_total_bytes) { +if (wrote_hole_at_eof) { + ret =ftruncate (fd, nr_total_bytes); +if (ret<0 ) { +error ("truncate source file to %lld bytes failed as %s" , + (long long )nr_total_bytes,strerror (errno)); + } + } +
src/seek_copy_tester.c line 275
Quoted 10 lines
src/seek_copy_tester.c new file +10
-0+ ret =write_zeros (fd, nr_total_bytes - off); +if (ret<0 ) { +error ("write_zeros to end of file failed as %s" , +strerror (errno)); + } + } + +out: +return ret; +}
It is shaping up nicely.
--Mark
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Hi Mark,
Quoted 14 lines · Mark Tinguely
Quoted 12 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu<[email protected]>---
src/seek_copy_tester.c new file +0
-0
Quoted 13 lines
src/seek_copy_tester.c line 111
Quoted 11 lines
src/seek_copy_tester.c new file +11
-0+static size_t +full_write (int fd,const void *buf,size_t count) +{ +size_t total =0 ; +const char *ptr = (const char *) buf; + +while (count>0 ) { +ssize_t n =write (fd, ptr, count); +if (n<0 ) { +if (errno ==EINTR ) +continue ;Wouldn't you want to stop the write loop if interrupted?
As this routine was called "full_write" which means it is expect to write as much as it can. So I would keep retrying if the process was interrupted by EINTR.
Would you please give some opinions whether this approach is not suitable in this circumstance?
Quoted 10 lines
src/seek_copy_tester.c line 117
Quoted 7 lines
src/seek_copy_tester.c new file +6
-0+error ("full_write() failed as %s" ,strerror (errno)); +break ; + } + +if (n ==0 ) { +error ("full_write() ZERO bytes transferred" );You can tell them how many (total) bytes were written before the error. Same in
full_pwrite()
This really a good idea!
Quoted 39 lines
Quoted 8 lines
src/seek_copy_tester.c new file +7
-0+create_data_and_holes(int fd, size_t nr_total_bytes, off_t start_offset, + uint64_t nr_skip_bytes, uint64_t nr_data_bytes, + int wrote_hole_at_eof) +{ + int ret = 0; +off_t total = nr_total_bytes; +off_t data_len = nr_data_bytes;src/seek_copy_tester.c
Quoted 10 lines
src/seek_copy_tester.c new file +7
-0+off_t off = start_offset; +char buf[BUF_SIZE ]; + +memset (buf,'A' ,sizeof (buf)); + + total -= start_offset; +while (total>0 ) {+
data_len=nr_data_bytes; /* see below */src/seek_copy_tester.c line 242
Quoted 2 lines
src/seek_copy_tester.c new file +2
-0+ do { + size_t nr_write = MIN(total, BUF_SIZE);There are 2 dependencies:
1) The lastnr_data_bytesdoes not exceed total (outer loop)
2) The remaining data size (data_len) could be less thanBUF_SIZE(ifdata_lenis not a multiple ofBUF_SIZEfor example).src/seek_copy_tester.c
Quoted 9 lines
src/seek_copy_tester.c new file +9
-0+if (full_pwrite (fd, buf, nr_write, off) != nr_write) { +error ("full_pwrite() failed as %s" ,strerror (errno)); + ret =-1 ; + goto out; + } + + off += nr_write; + data_len -= nr_write; + }while (data_len>0 );
Quoted 2 lines
data_lenis <= 0 so the inner loop will execute only once if you have more than one chunk of data.
Thanks for the comments!
So I'll revise the code logic as following:
1) Ensure "total > start_offset" before go into this routine, i.e, start offset should less than the total file size.
2) The left total should larger than data_len(nr_data_bytes).
3) Calculate the nr_write based on above two points.
Thanks,
-Jeff
Quoted 27 lines
Quoted 14 lines
src/seek_copy_tester.c new file +14
-0+ + off += (nr_skip_bytes + nr_data_bytes); + total -= off; + } + +if (off< nr_total_bytes) { +if (wrote_hole_at_eof) { + ret =ftruncate (fd, nr_total_bytes); +if (ret<0 ) { +error ("truncate source file to %lld bytes failed as %s" , + (long long )nr_total_bytes,strerror (errno)); + } + } +src/seek_copy_tester.c line 275
Quoted 10 lines
src/seek_copy_tester.c new file +10
-0+ ret =write_zeros (fd, nr_total_bytes - off); +if (ret<0 ) { +error ("write_zeros to end of file failed as %s" , +strerror (errno)); + } + } + +out: +return ret; +}It is shaping up nicely.
Quoted 2 lines
--Mark
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 32 lines · Jeff Liu
Hi Mark,
Quoted 14 lines · Mark Tinguely
Quoted 12 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu<[email protected]>---
src/seek_copy_tester.c new file +0
-0Quoted 13 lines
src/seek_copy_tester.c line 111
Quoted 11 lines
src/seek_copy_tester.c new file +11
-0+static size_t +full_write (int fd,const void *buf,size_t count) +{ +size_t total =0 ; +const char *ptr = (const char *) buf; + +while (count>0 ) { +ssize_t n =write (fd, ptr, count); +if (n<0 ) { +if (errno ==EINTR ) +continue ;Wouldn't you want to stop the write loop if interrupted?
Quoted 3 lines
As this routine was called "
full_write" which means it is expect to write as much as it can. So I would keep retrying if the process was interrupted by EINTR.
Would you please give some opinions whether this approach is not suitable in this circumstance?
Maybe I was thinking wrong. I was thinking if someone had killed the test and the write was interrupted by the signal, then you would give up the write loop.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 3 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu <[email protected]>
This has the same problems with $seq.out as 279, so I won't repeat them here.
.....
280 line 59
Quoted 10 lines
280 new file +10
-0+_cleanup() +{ + rm -f $src $dest +} + +# seek_copy_test_01() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 80991, write 4Kbytes, +# and then skip 195001 bytes for next write.
Oh, man, you didn't write a program to do this, do you? This is what xfs_io is for - to create arbitary file configurations as quickly as you can type them. Then all you need is a simple program that copies the extents, and the test can check everything else.
Quoted 5 lines
280 new file +5
-0+# this is intended to test data buffer lookup for DIRTY pages. +# verify results: +# 1. file size is identical. +# 2. perform cmp(1) to compare SRC and DEST file byte by byte. +test01()
280 line 74
Quoted 10 lines
280 new file +10
-0+{ + rm -f $src $dest + + $here/src/seek_copy_tester -P -O 0 -L 100m -s 80991 -k 195001 -l 4k $src $dest + + test $(stat --printf "%s" $src) = $(stat --printf "%s" $dest) || + echo "TEST01: file size check failed" >> $seq.out + + cmp $src $dest || + echo "TEST01: file bytes check failed" >> $seq.out
A quick hack (untested) to replace this file creation with xfs_io would be:
test01()
{
write_cmd="-c \"truncate 0\" -c \"falloc 0 100m\""
for i in `seq 0 1 100`; do
offset=$((80991 + $i * 195001))
write_cmd="$write_cmd -c \"pwrite $offset 4k\""
done
xfs_io -F -f $write_cmd $src
$here/scr/sparse_cp $src $dst
stat --printf "%s\n" $src $dst
cmp $src $dst >> $seq.out || _fail "file bytes check failed"
}280 line 83
Quoted 9 lines
280 new file +9
-0+} + +# seek_copy_test_02() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 0, write 16Kbytes, +# and then skip 8Mbytes for next write. +# Try flushing DIRTY pages to WRITEBACK mode, this is intended to +# test data buffer lookup in WRITEBACK pages.
There's no guarantee that that the seeks will occur while the pages are in the writeback. It's entirely dependent on IO latency - writing 16k of data to a disk cache will take less time than it takes to go back up into userspace and start the sparse copy. Indeed, i suspect that the 16x16k IOs that this tes does will fit all into that category even on basic SATA configs....
Also, you could the fadvise command in xfs_io to do this, as POSIX_FADV_DONTNEED will trigger async writeback -it will then skip invalidation of pages under writeback so they will remain in the cache. i.e. '-c "fadvise -d 0 100m"'
Ideally, we should add all the different sync methods to an xfs_io command...
280 line 104
Quoted 3 lines
280 new file +3
-0+# the first data extent offset start from 512, write 4Kbytes, +# and then skip 1Mbytes for next write. +# don't make holes at the end of file.
I'm not sure what this means - you always write zeros at the end of file, and the only difference is that "make holes at EOF" does an ftruncate to the total size before writing zeros up to it. It appears to me like you end up with the same file size and shape either way....
280.out line 1
Quoted 4 lines
280.out new file +1
-0@@ -0,0 +1 @@ +QA output created by 280
Normally we echo "silence is golden" to the output file in this case of no real output to indicate that this empty output file is intentional.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 9 lines · Dave Chinner
Quoted 3 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu <[email protected]>This has the same problems with $seq.out as 279, so I won't repeat them here.
.....
Quoted 12 lines
280 line 59
Quoted 10 lines
280 new file +10
-0+_cleanup() +{ + rm -f $src $dest +} + +# seek_copy_test_01() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 80991, write 4Kbytes, +# and then skip 195001 bytes for next write.Oh, man, you didn't write a program to do this, do you?
Unfortunately, I have already included file creation at seek_copy_tester :(
Quoted 4 lines
This is what
xfs_iois for - to create arbitary file configurations as quickly as you can type them. Then all you need is a simple program that copies the extents, and the test can check everything else.
Yes, xfs_io is pretty cool, and it really convenient for file creation for XFS.
I wrote it(create_data_and_holes()) in seek_copy_tester since I'd make it as a general SEEK_DATA/SEEK_HOLE tester for other file systems without this utility too.
Quoted 21 lines
Quoted 6 lines
280 new file +5
-0+# this is intended to test data buffer lookup for DIRTY pages. +# verify results: +# 1. file size is identical. +# 2. perform cmp(1) to compare SRC and DEST file byte by byte. +test01()280 line 74
Quoted 10 lines
280 new file +10
-0+{ + rm -f $src $dest + + $here/src/seek_copy_tester -P -O 0 -L 100m -s 80991 -k 195001 -l 4k $src $dest + + test $(stat --printf "%s" $src) = $(stat --printf "%s" $dest) || + echo "TEST01: file size check failed" >> $seq.out + + cmp $src $dest || + echo "TEST01: file bytes check failed" >> $seq.outA quick hack (untested) to replace this file creation with
xfs_iowould be:
test01()
Quoted 12 lines
{
write_cmd="-c \"truncate 0\" -c \"falloc 0 100m\""
for i in `seq 0 1 100`; do
offset=$((80991 + $i * 195001))
write_cmd="$write_cmd -c \"pwrite $offset 4k\""
done
xfs_io -F -f $write_cmd $src
$here/scr/sparse_cp $src $dst
stat --printf "%s\n" $src $dst
cmp $src $dst >> $seq.out || _fail "file bytes check failed"
}Thanks for this detailed info :).
Quoted 19 lines
280 line 83
Quoted 11 lines
280 new file +9
-0+} + +# seek_copy_test_02() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 0, write 16Kbytes, +# and then skip 8Mbytes for next write. +# Try flushing DIRTY pages to WRITEBACK mode, this is intended to +# test data buffer lookup in WRITEBACK pages.There's no guarantee that that the seeks will occur while the pages are in the writeback. It's entirely dependent on IO latency - writing 16k of data to a disk cache will take less time than it takes to go back up into userspace and start the sparse copy. Indeed, i suspect that the 16x16k IOs that this tes does will fit all into that category even on basic SATA configs....
Quoted 7 lines
Also, you could the fadvise command in
xfs_ioto do this, asPOSIX_FADV_DONTNEEDwill trigger async writeback -it will then skip invalidation of pages under writeback so they will remain in the cache. i.e. '-c "fadvise -d 0 100m"'Ideally, we should add all the different sync methods to an
xfs_iocommand...
Thanks again for the detained info.
It's definitely depending on the IO latency to test cover those page status conversion. I have verified the old patch with page probe routine on my laptop SATA disk controller, but not tried against other faster controllers. If we agree to make it as a general tester, maybe I can try to implement it by referring to xfs_io fadvise, I guess it use posix_fadvise(2), will check it later.
Quoted 10 lines
280 line 104
Quoted 4 lines
280 new file +3
-0+# the first data extent offset start from 512, write 4Kbytes, +# and then skip 1Mbytes for next write. +# don't make holes at the end of file.I'm not sure what this means - you always write zeros at the end of file, and the only difference is that "make holes at EOF" does an ftruncate to the total size before writing zeros up to it. It appears to me like you end up with the same file size and shape either way....
Oops! this is a code bug. I want to create a hole at EOF if possible when "-E(wrote_hole_at_eof)" option was specified. It can be fixed as below FIXME:
if (off < nr_total_bytes) {
if (wrote_hole_at_eof) {
ret = ftruncate(fd, nr_total_bytes);
if (ret < 0) {
error("truncate source file to %zu bytes failed as %s",
nr_total_bytes, strerror(errno));
}
goto out; *FIXME, break here *
}
ret = write_zeros(fd, nr_total_bytes - off);
if (ret < 0) {
error("write_zeros to end of file failed as %s",
strerror(errno));
}
}
}Quoted 9 lines
280.out line 1
Quoted 5 lines
280.out new file +1
-0@@ -0,0 +1 @@ +QA output created by 280Normally we echo "silence is golden" to the output file in this case of no real output to indicate that this empty output file is intentional.
Ok.
Thanks,
-Jeff
Quoted 4 lines
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 24 lines · Jeff Liu
Quoted 9 lines · Dave Chinner
Quoted 3 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu <[email protected]>This has the same problems with $seq.out as 279, so I won't repeat them here.
.....
Quoted 12 lines
Review
Quoted 10 lines
(quoted diff) +10
-0+_cleanup() +{ + rm -f $src $dest +} + +# seek_copy_test_01() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 80991, write 4Kbytes, +# and then skip 195001 bytes for next write.Oh, man, you didn't write a program to do this, do you?
Quoted 8 lines
Unfortunately, I have already included file creation at
seek_copy_tester:(Quoted 4 lines
This is what
xfs_iois for - to create arbitary file configurations as quickly as you can type them. Then all you need is a simple program that copies the extents, and the test can check everything else.Yes,
xfs_iois pretty cool, and it really convenient for file creation for XFS.
xfs_io is filesystem agnostic. Currently it needs the "-F" flag to tell it to work on non-xfs filesystems, but Eric posted patches a couple of days ago to remove that (i.e to automatically detect XFS filesystems and enable all the xfs specific stuff).
Quoted 2 lines
I wrote it(create_data_and_holes()) in
seek_copy_testersince I'd make it as a general SEEK_DATA/SEEK_HOLE tester for other file systems without this utility too.
xfs_io is used all throughout xfstests in generic tests. Just look at common.punch::_test_generic_punch as an example. That function uses xfs_io to test the different methods of perallocation and hole punching supported by a bunch of different filesystems in 3 different tests. IOWs, the generic tests use fallocate and the XFS specific tests use XFS ioctls, but all tests use xfs_io to run the commands....
Quoted 20 lines
Quoted 20 lines
Review
Quoted 7 lines
(quoted diff) +7
-0+# seek_copy_test_02() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 0, write 16Kbytes, +# and then skip 8Mbytes for next write. +# Try flushing DIRTY pages to WRITEBACK mode, this is intended to +# test data buffer lookup in WRITEBACK pages.There's no guarantee that that the seeks will occur while the pages are in the writeback. It's entirely dependent on IO latency - writing 16k of data to a disk cache will take less time than it takes to go back up into userspace and start the sparse copy. Indeed, i suspect that the 16x16k IOs that this tes does will fit all into that category even on basic SATA configs....
Also, you could the fadvise command in
xfs_ioto do this, asPOSIX_FADV_DONTNEEDwill trigger async writeback -it will then skip invalidation of pages under writeback so they will remain in the cache. i.e. '-c "fadvise -d 0 100m"'
Quoted 8 lines
Quoted 2 lines
Ideally, we should add all the different sync methods to an
xfs_iocommand...Thanks again for the detained info.
It's definitely depending on the IO latency to test cover those page status conversion. I have verified the old patch with page probe routine on my laptop SATA disk controller, but not tried against other faster controllers. If we agree to make it as a general tester, maybe I can try to implement it by referring toxfs_iofadvise, I guess it useposix_fadvise(2), will check it later.
Yes, it uses posix_fadvise64().
As it is, I spent 15 minutes adding support for sync_file_range() to xfs_io. The patch is attached below.
Quoted 10 lines
Quoted 9 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+# the first data extent offset start from 512, write 4Kbytes, +# and then skip 1Mbytes for next write. +# don't make holes at the end of file.I'm not sure what this means - you always write zeros at the end of file, and the only difference is that "make holes at EOF" does an ftruncate to the total size before writing zeros up to it. It appears to me like you end up with the same file size and shape either way....
Quoted 2 lines
Oops! this is a code bug. I want to create a hole at EOF if possible when "-E(wrote_hole_at_eof)" option was specified. It can be fixed as below FIXME:
Yes, that'd work ;)
Cheers,
Dave.
Signature · 19 lines
Dave Chinner [email protected] xfs_io: add sync_file_range support From: Dave Chinner <[email protected]> Add sync_file_range support to xfs_io to allow fine grained control of data writeback and syncing on a given file. Reviewed-by: Dave Chinner <[email protected]> --- io/Makefile | 5 ++ io/init.c | 1 + io/io.h | 6 +++ io/sync_file_range.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 19 +++++++++ 5 files changed, 138 insertions(+), 0 deletions(-)
io/Makefile +5 -0
@@ -58,6 +58,11 @@ CFILES += inject.c resblks.c LCFLAGS += -DHAVE_INJECT -DHAVE_RESBLKS endif +ifeq ($(PKG_PLATFORM),linux) +CFILES += sync_file_range.c +LCFLAGS += -DHAVE_SYNC_FILE_RANGE +endif + ifeq ($(ENABLE_READLINE),yes) LLDLIBS += $(LIBREADLINE) $(LIBTERMCAP) endif
io/init.c +1 -0
@@ -78,6 +78,7 @@ init_commands(void)sendfile_init ();shutdown_init ();truncate_init (); +sync_range_init (); } static int
io/io.h +6 -0
@@ -141,3 +141,9 @@ extern void fiemap_init(void);#else #define fiemap_init () do { } while (0)#endif + +#ifdef HAVE_SYNC_FILE_RANGE +extern void sync_range_init (void ); +#else +#define sync_range_init () do { } while (0) +#endif
io/sync_file_range.c new file +107 -0
107 lines not on this page · raw message
man/man8/xfs_io.8 +19 -0
@@ -283,6 +283,25 @@ See the .B fsync command. .TP +.BI "sync_range [ \-a | \-b | \-w ] offset length " +On platforms which support it, allows control of syncing a range of the file to +disk. With no options, SYNC_FILE_RANGE_WRITE is implied on the range supplied. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-a +wait for IO in the given range to finish after writing +(SYNC_FILE_RANGE_WAIT_AFTER). +.TP +.B \-b +wait for IO in the given range to finish before writing +(SYNC_FILE_RANGE_WAIT_BEFORE). +.TP +.B \-w +start writeback of dirty data in the given range (SYNC_FILE_RANGE_WRITE). +.RE +.PD +.TP .BI resvsp " offset length" Allocates reserved, unwritten space for part of a file using the XFS_IOC_RESVSP system call described in the
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 32 lines · Dave Chinner
Quoted 31 lines · Jeff Liu
Quoted 9 lines · Dave Chinner
Quoted 3 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu <[email protected]>This has the same problems with $seq.out as 279, so I won't repeat them here.
.....
Quoted 12 lines
Review
Quoted 10 lines
(quoted diff) +10
-0+_cleanup() +{ + rm -f $src $dest +} + +# seek_copy_test_01() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 80991, write 4Kbytes, +# and then skip 195001 bytes for next write.Oh, man, you didn't write a program to do this, do you?
Unfortunately, I have already included file creation at
seek_copy_tester:(Quoted 4 lines
This is what
xfs_iois for - to create arbitary file configurations as quickly as you can type them. Then all you need is a simple program that copies the extents, and the test can check everything else.
Quoted 6 lines
Quoted 1 line
Yes,
xfs_iois pretty cool, and it really convenient for file creation for XFS.
xfs_iois filesystem agnostic. Currently it needs the "-F" flag to tell it to work on non-xfs filesystems, but Eric posted patches a couple of days ago to remove that (i.e to automatically detect XFS filesystems and enable all the xfs specific stuff).
Awesome! I just playing around it, so far so cool. :)
Quoted 11 lines
Quoted 3 lines
I wrote it(create_data_and_holes()) in
seek_copy_testersince I'd make it as a general SEEK_DATA/SEEK_HOLE tester for other file systems without this utility too.
xfs_iois used all throughout xfstests in generic tests. Just look atcommon.punch::_test_generic_punchas an example. That function usesxfs_ioto test the different methods of perallocation and hole punching supported by a bunch of different filesystems in 3 different tests. IOWs, the generic tests use fallocate and the XFS specific tests use XFS ioctls, but all tests usexfs_ioto run the commands....
Now I understand your opinions, those changes will be reflect in V3.
Quoted 30 lines
Quoted 21 lines
Quoted 21 lines
Review
Quoted 8 lines
(quoted diff) +7
-0+# seek_copy_test_02() +# create a 100Mytes file in preallocation mode. +# fallocate offset start from 0. +# the first data extent offset start from 0, write 16Kbytes, +# and then skip 8Mbytes for next write. +# Try flushing DIRTY pages to WRITEBACK mode, this is intended to +# test data buffer lookup in WRITEBACK pages.There's no guarantee that that the seeks will occur while the pages are in the writeback. It's entirely dependent on IO latency - writing 16k of data to a disk cache will take less time than it takes to go back up into userspace and start the sparse copy. Indeed, i suspect that the 16x16k IOs that this tes does will fit all into that category even on basic SATA configs....
Also, you could the fadvise command in
xfs_ioto do this, asPOSIX_FADV_DONTNEEDwill trigger async writeback -it will then skip invalidation of pages under writeback so they will remain in the cache. i.e. '-c "fadvise -d 0 100m"'Quoted 8 lines
Quoted 2 lines
Ideally, we should add all the different sync methods to an
xfs_iocommand...Thanks again for the detained info.
It's definitely depending on the IO latency to test cover those page status conversion. I have verified the old patch with page probe routine on my laptop SATA disk controller, but not tried against other faster controllers. If we agree to make it as a general tester, maybe I can try to implement it by referring toxfs_iofadvise, I guess it useposix_fadvise(2), will check it later.
Quoted 4 lines
Yes, it uses
posix_fadvise64().As it is, I spent 15 minutes adding support for
sync_file_range()toxfs_io. The patch is attached below.
I'll apply your patch to try it out.
Thanks,
-Jeff
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Review
Quoted 4 lines
(quoted diff) +3
-0+# the first data extent offset start from 512, write 4Kbytes, +# and then skip 1Mbytes for next write. +# don't make holes at the end of file.I'm not sure what this means - you always write zeros at the end of file, and the only difference is that "make holes at EOF" does an ftruncate to the total size before writing zeros up to it. It appears to me like you end up with the same file size and shape either way....
Quoted 8 lines
Quoted 2 lines
Oops! this is a code bug. I want to create a hole at EOF if possible when "-E(wrote_hole_at_eof)" option was specified. It can be fixed as below FIXME:
Yes, that'd work ;)
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu<[email protected]>src/seek_copy_tester.c new file +3
-0+static int +do_extent_copy (int src_fd,int dest_fd,off_t data_off,off_t hole_off) +{
...
src/seek_copy_tester.c line 308
Quoted 4 lines
src/seek_copy_tester.c new file +4
-0+ +while (len>0 ) { +memset (buf,0 ,sizeof (buf)); +ssize_t nr_read =read (src_fd, buf,BUF_SIZE );
#RCJ The memset above is unnecessary.
Quoted 5 lines
src/seek_copy_tester.c new file +5
-0+static int +copy_extents (int src_fd,int dest_fd,off_t src_total_size) +{ +int ret =0 ; +unsigned int i =0 ;
...
src/seek_copy_tester.c
Quoted 3 lines
src/seek_copy_tester.c new file +3
-0+ ++i; + seek_start = hole_pos; + }while (seek_start< src_total_size);
#RCJ i is unused.
Other than the comments above, this version of the test looks good.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Hi Rich,
Sorry for my late response!
Quoted 30 lines · Rich Johnston
Quoted 10 lines · Jeff Liu
Introduce 280 for SEEK_DATA/SEEK_HOLE copy check.
Signed-off-by Jie Liu<[email protected]>src/seek_copy_tester.c new file +3
-0+static int +do_extent_copy (int src_fd,int dest_fd,off_t data_off,off_t hole_off) +{...
src/seek_copy_tester.c line 308
Quoted 4 lines
src/seek_copy_tester.c new file +4
-0+ +while (len>0 ) { +memset (buf,0 ,sizeof (buf)); +ssize_t nr_read =read (src_fd, buf,BUF_SIZE );#RCJ The memset above is unnecessary.
Quoted 5 lines
src/seek_copy_tester.c new file +5
-0+static int +copy_extents (int src_fd,int dest_fd,off_t src_total_size) +{ +int ret =0 ; +unsigned int i =0 ;...
Quoted 4 lines
src/seek_copy_tester.c
Quoted 3 lines
src/seek_copy_tester.c new file +3
-0+ ++i; + seek_start = hole_pos; + }while (seek_start< src_total_size);#RCJ i is unused.
Thanks for the review, I'll fix them later.
-Jeff
Quoted 8 lines
Other than the comments above, this version of the test looks good.
Reviewed-by Rich Johnston<[email protected]>_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs