* bug#8061: Introduce SEEK_DATA/SEEK_HOLE to extent_scan module
[not found] ` <3E3FBE56-4D89-44A4-94ED-13F3D1F693A3@oracle.com>
@ 2011-08-26 9:43 ` Jeff Liu
0 siblings, 0 replies; only message in thread
From: Jeff Liu @ 2011-08-26 9:43 UTC (permalink / raw)
To: 8061; +Cc: zfs-discuss, linux-btrfs, chris.mason
Dear All,
As the SEEK_HOLE/SEEK_DATA has been implemented on Btrfs in 3.1.0+ and
Glibc, I have worked out a new version for your guys review.
Changes:
======
extent_scan.[c|h]:
1. add a function pointer to "struct extent_scan":
/* Scan method. */
bool (*extent_scan) (struct extent_scan *scan);
2. add a structure item to indicate seek back issue maybe occurred:
/* Failed to seek back to position 0 or not. */
bool seek_back_failed;
If the file system support SEEK_HOLE, the file offset will pointed to
somewhere > 0, so need to
seek back to the beginning after support_seek_hole() checking for the
proceeding extent scan.
3. rename extent_scan to fiemap_extent_scan.
4. add a new seek_extent_scan method.
5. add a new method to check SEEK stuff is supported or not.
if the underlaying file system support SEEK_HOLE, assign
seek_extent_scan to scan->extent_scan, or else, fiemap_extent_scan()
will be assigned to it.
copy.c:
1. pass src_total_size to extent_scan_init ().
2. for the first round extent scan, we need to seek back to position 0
too, if the data extent is started at the beginning of source file.
Tested:
======
1. make syntax-check.
2. verify a copied sparse file with 4697 extents on btrfs
jeff@pibroch:~/gnu/coreutils$ python -c "f=open('/btrfs/sparse_test',
'w'); [(f.seek(x) or f.write(str(x))) for x in range(1, 1000000000,
99999)]; f.close()"
jeff@pibroch:~/gnu/coreutils$ ./src/cp --sparse=always
/btrfs/sparse_test /btrfs/sp.seek
jeff@pibroch:~/gnu/coreutils$ cmp /btrfs/sparse_test /btrfs/sp.seek
jeff@pibroch:~/gnu/coreutils$ echo $?
0
Also, the previous patch was developed on Solaris ZFS, but my test env
was lost now. :( so anyone can help testing it on ZFS would be
appreciated!!
From 5892744f977a06b5557042682c39fd007eec8030 Mon Sep 17 00:00:00 2001
From: Jie Liu <jeff.liu@oracle.com>
Date: Fri, 26 Aug 2011 17:11:33 +0800
Subject: [PATCH 1/1] copy: add SEEK_DATA/SEEK_HOLE support to
extent_scan module
* src/extent_scan.h: introduce src_total_size to struct extent_info, we
need it for lseek(2) iteration, add seek_back_failed to indicate that the
seek back to position 0 failed in seek captical check or not, and it can
be used for further debugging IMHO.
add bool (*extent_scan) (struct extent_scan *scan) to switch the scan
method.
* src/extent_scan.c: implement a new seek_scan_read() through SEEK_DATA
and SEEK_HOLE.
* src/copy.c: a few code changes according to the new extent call interface.
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
---
src/copy.c | 26 +++++++++-
src/extent-scan.c | 149
++++++++++++++++++++++++++++++++++++++++++++++++++--
src/extent-scan.h | 16 +++++-
3 files changed, 183 insertions(+), 8 deletions(-)
diff --git a/src/copy.c b/src/copy.c
index bc4d7bd..c5e8714 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -309,7 +309,18 @@ extent_copy (int src_fd, int dest_fd, char *buf,
size_t buf_size,
We may need this at the end, for a final ftruncate. */
off_t dest_pos = 0;
- extent_scan_init (src_fd, &scan);
+ bool init_ok = extent_scan_init (src_fd, src_total_size, &scan);
+ /* If the underlaying file system support SEEK_HOLE, but failed
+ to seek back to position 0 after the initial seek checking,
+ let extent copy failure in this case. */
+ if (! init_ok)
+ {
+ if (scan.seek_back_failed)
+ error (0, errno,
+ _("%s: extent_scan_init () failed, cannot seek back to
position 0"),
+ quote (src_name));
+ return false;
+ }
*require_normal_copy = false;
bool wrote_hole_at_eof = true;
@@ -356,6 +367,19 @@ extent_copy (int src_fd, int dest_fd, char *buf,
size_t buf_size,
wrote_hole_at_eof = false;
+ /* For the first round scan, if the data extent start at the
+ beginning, and the current file pointer is not at position
+ 0, set it back first, otherwise, we'll read from undesired
+ file offset. */
+ if (ext_start == 0 && lseek (src_fd, 0, SEEK_CUR) != 0)
+ {
+ if (lseek (src_fd, 0, SEEK_SET) < 0)
+ {
+ error (0, errno, _("cannot lseek %s"), quote (src_name));
+ return false;
+ }
+ }
+
if (hole_size)
{
if (lseek (src_fd, ext_start, SEEK_SET) < 0)
diff --git a/src/extent-scan.c b/src/extent-scan.c
index 37445b8..c835b63 100644
--- a/src/extent-scan.c
+++ b/src/extent-scan.c
@@ -27,6 +27,12 @@
#include "fiemap.h"
#include "xstrtol.h"
+#ifndef SEEK_DATA
+# define SEEK_DATA 3 /* Seek to next data. */
+#endif
+#ifndef SEEK_HOLE
+# define SEEK_HOLE 4 /* Seek to next hole. */
+#endif
/* Work around Linux kernel issues on BTRFS and EXT4 before 2.6.39.
FIXME: remove in 2013, or whenever we're pretty confident
@@ -65,10 +71,48 @@ extent_need_sync (void)
#endif
}
+static bool
+support_seek_hole (struct extent_scan *scan)
+{
+ off_t hole_pos;
+
+# ifdef _PC_MIN_HOLE_SIZE
+ /* To determine if the underlaying file system support
+ SEEK_HOLE, if not, fall back to fiemap extent scan or
+ the standard copy. */
+ if (fpathconf (scan->fd, _PC_MIN_HOLE_SIZE) < 0)
+ return false;
+# endif
+
+ /* Inspired by STAR, If we have been compiled on an OS that
+ supports SEEK_HOLE but run on an OS that does not support
+ SEEK_HOLE, we get EINVAL. If the underlying file system
+ does not support the SEEK_HOLE call, we get ENOTSUP, fall
+ back to the fiemap scan or standard copy in either case. */
+ hole_pos = lseek (scan->fd, (off_t) 0, SEEK_HOLE);
+ if (hole_pos < 0)
+ {
+ if (errno == EINVAL || errno == ENOTSUP)
+ return false;
+ }
+
+ /* Seek back to position 0 first if we detected a real hole. */
+ if (hole_pos > 0)
+ {
+ if (lseek (scan->fd, (off_t) 0, SEEK_SET) != 0)
+ {
+ scan->seek_back_failed = true;
+ return false;
+ }
+ }
+
+ return true;
+}
+
/* Allocate space for struct extent_scan, initialize the entries if
necessary and return it as the input argument of
extent_scan_read(). */
-extern void
-extent_scan_init (int src_fd, struct extent_scan *scan)
+extern bool
+extent_scan_init (int src_fd, size_t src_total_size, struct extent_scan
*scan)
{
scan->fd = src_fd;
scan->ei_count = 0;
@@ -76,17 +120,110 @@ extent_scan_init (int src_fd, struct extent_scan
*scan)
scan->scan_start = 0;
scan->initial_scan_failed = false;
scan->hit_final_extent = false;
- scan->fm_flags = extent_need_sync () ? FIEMAP_FLAG_SYNC : 0;
+ scan->seek_back_failed = false;
+
+ if (support_seek_hole (scan))
+ {
+ scan->src_total_size = src_total_size;
+ scan->extent_scan = seek_extent_scan;
+ }
+ else
+ {
+ /* The underlying file system support SEEK_HOLE, but failed
+ to seek back to position 0 after seek checking, Oops! */
+ if (scan->seek_back_failed)
+ return false;
+
+ scan->extent_scan = fiemap_extent_scan;
+ scan->fm_flags = extent_need_sync () ? FIEMAP_FLAG_SYNC : 0;
+ }
+
+ return true;
+}
+
+extern inline bool
+extent_scan_read (struct extent_scan *scan)
+{
+ return scan->extent_scan (scan);
+}
+
+extern bool
+seek_extent_scan (struct extent_scan *scan)
+{
+ off_t data_pos, hole_pos;
+ union { struct extent_info ei; char c[4096]; } extent_buf;
+ struct extent_info *ext_info = &extent_buf.ei;
+ enum { count = (sizeof extent_buf / sizeof *ext_info) };
+ verify (count != 0);
+
+ memset (&extent_buf, 0, sizeof extent_buf);
+
+ unsigned int i = 0;
+ /* If lseek(2) failed and the errno is set to ENXIO, for
+ SEEK_DATA there are no more data regions past the supplied
+ offset. For SEEK_HOLE, there are no more holes past the
+ supplied offset. Set scan->hit_final_extent to true for
+ either case. */
+ do {
+ data_pos = lseek (scan->fd, scan->scan_start, SEEK_DATA);
+ if (data_pos < 0)
+ {
+ if (errno == ENXIO)
+ {
+ scan->hit_final_extent = true;
+ return true;
+ }
+ return false;
+ }
+
+ /* We hit the final extent if the data offset is equal to
+ the source file size. */
+ if (data_pos == scan->src_total_size)
+ {
+ scan->hit_final_extent = true;
+ break;
+ }
+
+ hole_pos = lseek (scan->fd, data_pos, SEEK_HOLE);
+ if (hole_pos < 0)
+ {
+ if (errno != ENXIO)
+ return false;
+ else
+ {
+ scan->hit_final_extent = true;
+ return true;
+ }
+ }
+
+ ext_info[i].ext_logical = data_pos;
+ ext_info[i].ext_length = hole_pos - data_pos;
+ scan->scan_start = hole_pos;
+ ++i;
+ } while (scan->scan_start < scan->src_total_size && i < count);
+
+ scan->ei_count = i;
+ scan->ext_info = xnmalloc (scan->ei_count, sizeof (struct extent_info));
+
+ for (i = 0; i < scan->ei_count; i++)
+ {
+ assert (ext_info[i].ext_logical <= OFF_T_MAX);
+
+ scan->ext_info[i].ext_logical = ext_info[i].ext_logical;
+ scan->ext_info[i].ext_length = ext_info[i].ext_length;
+ }
+
+ return true;
}
-#ifdef __linux__
+#if defined __linux__
# ifndef FS_IOC_FIEMAP
# define FS_IOC_FIEMAP _IOWR ('f', 11, struct fiemap)
# endif
/* Call ioctl(2) with FS_IOC_FIEMAP (available in linux 2.6.27) to
obtain a map of file extents excluding holes. */
extern bool
-extent_scan_read (struct extent_scan *scan)
+fiemap_extent_scan (struct extent_scan *scan)
{
unsigned int si = 0;
struct extent_info *last_ei IF_LINT ( = scan->ext_info);
@@ -212,7 +349,7 @@ extent_scan_read (struct extent_scan *scan)
}
#else
extern bool
-extent_scan_read (struct extent_scan *scan ATTRIBUTE_UNUSED)
+fiemap_extent_scan (struct extent_scan *scan ATTRIBUTE_UNUSED)
{
scan->initial_scan_failed = true;
errno = ENOTSUP;
diff --git a/src/extent-scan.h b/src/extent-scan.h
index 5b4ded5..e751810 100644
--- a/src/extent-scan.h
+++ b/src/extent-scan.h
@@ -38,6 +38,9 @@ struct extent_scan
/* File descriptor of extent scan run against. */
int fd;
+ /* Source file size, i.e, (struct stat) &statbuf.st_size. */
+ size_t src_total_size;
+
/* Next scan start offset. */
off_t scan_start;
@@ -47,6 +50,9 @@ struct extent_scan
/* How many extent info returned for a scan. */
uint32_t ei_count;
+ /* Failed to seek back to position 0 or not. */
+ bool seek_back_failed;
+
/* If true, fall back to a normal copy, either set by the
failure of ioctl(2) for FIEMAP or lseek(2) with SEEK_DATA. */
bool initial_scan_failed;
@@ -54,14 +60,22 @@ struct extent_scan
/* If true, the total extent scan per file has been finished. */
bool hit_final_extent;
+ /* Scan method. */
+ bool (*extent_scan) (struct extent_scan *scan);
+
/* Extent information: a malloc'd array of ei_count structs. */
struct extent_info *ext_info;
};
-void extent_scan_init (int src_fd, struct extent_scan *scan);
+bool extent_scan_init (int src_fd, size_t src_total_size,
+ struct extent_scan *scan);
bool extent_scan_read (struct extent_scan *scan);
+bool fiemap_extent_scan (struct extent_scan *scan);
+
+bool seek_extent_scan (struct extent_scan *scan);
+
static inline void
extent_scan_free (struct extent_scan *scan)
{
--
1.7.4.1
Thanks,
-Jeff
On 04/19/2011 04:51 PM, Jeff liu wrote:
>> Hi All,
>>
>> Please ignore the current patch, I will submit another patch with a few fixes soon.
> Now the new patch set coming,
>
> In previous post, I have tried to change the extent_scan_init() interface by adding a new argument to indicate the source file size,
> this will reduce the overhead of call fstat(2) in extent_scan_read(), since the file size is definitely needed for SEEK* stuff, however, the file size is redundant for FIEMAP.
> so I changed my idea to keep extent_scan_init() as before, instead, to retrieve the file size in extent_scan_read() when launching the first scan, one benefit is, there is nothing need to
> be modified in extent_copy() for this patch.
>
> Tests:
> ====
> A new test sparse-lseek was introduced in this post, it make use of the sparse file generation function in Perl, and do `cmp` against the target copied file.
> I have also took a look at the `sdb` utility shipped with ZFS, but did not found any interesting stuff can be used for this test.
>
> Test run passed on my environment as below,
>
> bash-3.00# make check TESTS=cp/sparse-lseek VERBOSE=yes
> make check-TESTS
> make[1]: Entering directory `/coreutils/tests'
> make[2]: Entering directory `/coreutils/tests'
> PASS: cp/sparse-lseek
> =============
> 1 test passed
> =============
> make[2]: Leaving directory `/coreutils/tests'
> make[1]: Leaving directory `/coreutils/tests'
> GEN vc_exe_in_TESTS
> No differences encountered
>
> Manual tests:
> ===========
> 1. Ensure trailing blanks, test 0 size sparse file, non-sparse file, sparse file with hole start and hole end.
> 2. make syntax-check failed, I have no idea of this issue at the moment, I also tried to run make distcheck, looks the package building, install and uninstall procedures all passed,
> but it also failed at the final stage, am I missing something here?
>
> The logs which were shown as following,
> bash-3.00# make syntax-check
> GFDL_version
> awk: syntax error near line 1
> awk: bailing out near line 1
> make: *** [sc_GFDL_version.z] Error 2
>
> make distcheck:
> ==============
> ......
> make[1]: Entering directory `/coreutils'
> GEN check-ls-dircolors
> make my-distcheck
> make[2]: Entering directory `/coreutils'
> make syntax-check
> make[3]: Entering directory `/coreutils'
> GFDL_version
> awk: syntax error near line 1
> awk: bailing out near line 1
> make[3]: *** [sc_GFDL_version.z] Error 2
> make[3]: Leaving directory `/coreutils'
> make[2]: *** [my-distcheck] Error 2
> make[2]: Leaving directory `/coreutils'
> make[1]: *** [distcheck-hook] Error 2
> make[1]: Leaving directory `/coreutils'
> make: *** [distcheck] Error 1
>
>
>
> Below is the revised patch,
>
> From 4f966c1fe6226f3f711faae120cd8bea78e722b8 Mon Sep 17 00:00:00 2001
> From: Jie Liu<jeff.liu@oracle.com>
> Date: Tue, 19 Apr 2011 15:24:50 -0700
> Subject: [PATCH 1/1] copy: add SEEK_DATA/SEEK_HOLE support to extent_scan module
>
> * src/extent_scan.h: introduce src_total_size to struct extent_info, we
> need it for lseek(2) iteration.
> * src/extent_scan.c: implement a new extent_scan_read() through SEEK_DATA
> and SEEK_HOLE if those stuff are supported.
> * tests/cp/sparse-lseek: add a new test for lseek(2) extent copy.
>
> Signed-off-by: Jie Liu<jeff.liu@oracle.com>
> ---
> src/extent-scan.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++
> src/extent-scan.h | 5 ++
> tests/Makefile.am | 1 +
> tests/cp/sparse-lseek | 56 +++++++++++++++++++++++
> 4 files changed, 181 insertions(+), 0 deletions(-)
> create mode 100755 tests/cp/sparse-lseek
>
> diff --git a/src/extent-scan.c b/src/extent-scan.c
> index da7eb9d..a54eca0 100644
> --- a/src/extent-scan.c
> +++ b/src/extent-scan.c
> @@ -17,7 +17,9 @@
> Written by Jie Liu (jeff.liu@oracle.com). */
>
> #include<config.h>
> +#include<fcntl.h>
> #include<sys/types.h>
> +#include<sys/stat.h>
> #include<sys/ioctl.h>
> #include<sys/utsname.h>
> #include<assert.h>
> @@ -71,6 +73,9 @@ extent_scan_init (int src_fd, struct extent_scan *scan)
> scan->initial_scan_failed = false;
> scan->hit_final_extent = false;
> scan->fm_flags = extent_need_sync () ? FIEMAP_FLAG_SYNC : 0;
> +#if defined (SEEK_DATA)&& defined (SEEK_HOLE)
> + scan->src_total_size = 0;
> +#endif
> }
>
> #ifdef __linux__
> @@ -204,6 +209,120 @@ extent_scan_read (struct extent_scan *scan)
>
> return true;
> }
> +#elif defined (SEEK_HOLE)&& defined (SEEK_DATA)
> +extern bool
> +extent_scan_read (struct extent_scan *scan)
> +{
> + off_t data_pos, hole_pos;
> + union { struct extent_info ei; char c[4096]; } extent_buf;
> + struct extent_info *ext_info =&extent_buf.ei;
> + enum { count = (sizeof extent_buf / sizeof *ext_info) };
> + verify (count != 0);
> +
> + memset (&extent_buf, 0, sizeof extent_buf);
> +
> + if (scan->scan_start == 0)
> + {
> +# ifdef _PC_MIN_HOLE_SIZE
> + /* To determine if the underlaying file system support
> + SEEK_HOLE. If not, fall back to the standard copy. */
> + if (fpathconf (scan->fd, _PC_MIN_HOLE_SIZE)< 0)
> + {
> + scan->initial_scan_failed = true;
> + return false;
> + }
> +# endif
> +
> + /* If we have been compiled on an OS that supports SEEK_HOLE
> + but run on an OS that does not support SEEK_HOLE, we get
> + EINVAL. If the underlying file system does not support the
> + SEEK_HOLE call, we get ENOTSUP, setting initial_scan_failed
> + to true to fall back to the standard copy in either case. */
> + hole_pos = lseek (scan->fd, (off_t) 0, SEEK_HOLE);
> + if (hole_pos< 0)
> + {
> + if (errno == EINVAL || errno == ENOTSUP)
> + scan->initial_scan_failed = true;
> + return false;
> + }
> +
> + /* Seek back to position 0 first. */
> + if (hole_pos> 0)
> + {
> + if (lseek (scan->fd, (off_t) 0, SEEK_SET)< 0)
> + return false;
> + }
> +
> + struct stat sb;
> + if (fstat (scan->fd,&sb)< 0)
> + return false;
> +
> + /* This is definitely not a sparse file, we treat it as a big extent. */
> + if (hole_pos>= sb.st_size)
> + {
> + scan->ei_count = 1;
> + scan->ext_info = xnmalloc (scan->ei_count, sizeof (struct extent_info));
> + scan->ext_info[0].ext_logical = 0;
> + scan->ext_info[0].ext_length = sb.st_size;
> + scan->hit_final_extent = true;
> + return true;
> + }
> + scan->src_total_size = sb.st_size;
> + }
> +
> + unsigned int i = 0;
> + /* If lseek(2) failed and the errno is set to ENXIO, for
> + SEEK_DATA there are no more data regions past the supplied
> + offset. For SEEK_HOLE, there are no more holes past the
> + supplied offset. Set scan->hit_final_extent to true in
> + either case. */
> + while (scan->scan_start< scan->src_total_size&& i< count)
> + {
> + data_pos = lseek (scan->fd, scan->scan_start, SEEK_DATA);
> + if (data_pos< 0)
> + {
> + if (errno == ENXIO)
> + {
> + scan->hit_final_extent = true;
> + break;
> + }
> + return false;
> + }
> +
> + hole_pos = lseek (scan->fd, data_pos, SEEK_HOLE);
> + if (hole_pos< 0)
> + {
> + if (errno == ENXIO)
> + {
> + scan->hit_final_extent = true;
> + hole_pos = scan->src_total_size;
> + if (data_pos< hole_pos)
> + goto preserve_ext_info;
> + break;
> + }
> + return false;
> + }
> +
> +preserve_ext_info:
> + ext_info[i].ext_logical = data_pos;
> + ext_info[i].ext_length = hole_pos - data_pos;
> + scan->scan_start = hole_pos;
> + ++i;
> + }
> +
> + scan->ei_count = i;
> + scan->ext_info = xnmalloc (scan->ei_count, sizeof (struct extent_info));
> +
> + for (i = 0; i< scan->ei_count; i++)
> + {
> + assert (ext_info[i].ext_logical<= OFF_T_MAX);
> +
> + scan->ext_info[i].ext_logical = ext_info[i].ext_logical;
> + scan->ext_info[i].ext_length = ext_info[i].ext_length;
> + }
> +
> + return (lseek (scan->fd, (off_t) 0, SEEK_SET)< 0) ? false : true;
> +}
> #else
> extern bool
> extent_scan_read (struct extent_scan *scan ATTRIBUTE_UNUSED)
> diff --git a/src/extent-scan.h b/src/extent-scan.h
> index 5b4ded5..4fc05c6 100644
> --- a/src/extent-scan.h
> +++ b/src/extent-scan.h
> @@ -38,6 +38,11 @@ struct extent_scan
> /* File descriptor of extent scan run against. */
> int fd;
>
> +# if defined (SEEK_DATA)&& defined (SEEK_HOLE)
> + /* Source file size, i.e, (struct stat)&statbuf.st_size. */
> + size_t src_total_size;
> +#endif
> +
> /* Next scan start offset. */
> off_t scan_start;
>
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 685eb52..6c596b9 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -28,6 +28,7 @@ root_tests = \
> cp/cp-mv-enotsup-xattr \
> cp/capability \
> cp/sparse-fiemap \
> + cp/sparse-lseek \
> dd/skip-seek-past-dev \
> install/install-C-root \
> ls/capability \
> diff --git a/tests/cp/sparse-lseek b/tests/cp/sparse-lseek
> new file mode 100755
> index 0000000..5b8f2c1
> --- /dev/null
> +++ b/tests/cp/sparse-lseek
> @@ -0,0 +1,56 @@
> +#!/bin/sh
> +# Test cp --sparse=always through lseek(SEEK_DATA/SEEK_HOLE) copy
> +
> +# Copyright (C) 2010-2011 Free Software Foundation, Inc.
> +
> +# 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 3 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, see<http://www.gnu.org/licenses/>.
> +
> +. "${srcdir=.}/init.sh"; path_prepend_ ../src
> +print_ver_ cp
> +$PERL -e 1 || skip_test_ 'you lack perl'
> +
> +zfsdisk=diskX
> +zfspool=seektest
> +
> +require_root_
> +
> +cwd=$PWD
> +cleanup_() { zpool destroy $zfspool; }
> +
> +skip=0
> +mkfile 128m "$cwd/$zfsdisk" || skip=1
> +
> +# Check if the seektest pool is already exists
> +zpool list $zfspool 2>/dev/null&&
> + skip_test_ "$zfspool already exists"
> +
> +# Create pool and verify if it is mounted automatically
> +zpool create $zfspool "$cwd/$zfsdisk" || skip=1
> +zpool list $zfspool>/dev/null || skip=1
> +
> +test $skip = 1&& skip_test_ "insufficient ZFS support"
> +
> +for i in $(seq 1 2 21); do
> + for j in 1 2 31 100; do
> + $PERL -e 'BEGIN { $n = '$i' * 1024; *F = *STDOUT }' \
> + -e 'for (1..'$j') { sysseek (*F, $n, 1)' \
> + -e '&& syswrite (*F, chr($_)x$n) or die "$!"}'> /$zfspool/j1 || fail=1
> +
> + cp --sparse=always /$zfspool/j1 /$zfspool/j2 || fail=1
> + cmp /$zfspool/j1 /$zfspool/j2 || fail=1
> + test $fail = 1&& break 2
> + done
> +done
> +
> +Exit $fail
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2011-08-26 9:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <2DB776C1-EF34-423D-8BE5-71C2F49DFF01@oracle.com>
[not found] ` <BE690E2C-C275-4B28-8ACB-9616D367EF96@oracle.com>
[not found] ` <3E3FBE56-4D89-44A4-94ED-13F3D1F693A3@oracle.com>
2011-08-26 9:43 ` bug#8061: Introduce SEEK_DATA/SEEK_HOLE to extent_scan module Jeff Liu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.