]> git.proxmox.com Git - mirror_zfs-debian.git/commitdiff
New upstream version 0.7.3
authorAron Xu <aron@debian.org>
Tue, 31 Oct 2017 10:22:52 +0000 (18:22 +0800)
committerAron Xu <aron@debian.org>
Tue, 31 Oct 2017 10:22:52 +0000 (18:22 +0800)
48 files changed:
META
Makefile.am
Makefile.in
cmd/zed/zed_conf.c
config/deb.am
configure
contrib/dracut/90zfs/module-setup.sh.in
contrib/initramfs/hooks/zfs
contrib/initramfs/scripts/local-top/zfs
contrib/initramfs/scripts/zfs
include/sys/arc.h
include/sys/dmu_send.h
include/sys/dsl_dataset.h
lib/libspl/Makefile.am
lib/libspl/Makefile.in
lib/libzfs/libzfs.pc
lib/libzfs/libzfs_core.pc
lib/libzfs/libzfs_import.c
lib/libzfs/libzfs_iter.c
lib/libzfs/libzfs_sendrecv.c
module/icp/algs/sha1/sha1.c
module/zfs/arc.c
module/zfs/dbuf.c
module/zfs/dmu_send.c
module/zfs/vdev_label.c
module/zfs/zfs_vnops.c
rpm/generic/zfs-dkms.spec.in
rpm/generic/zfs-kmod.spec.in
rpm/generic/zfs.spec.in
rpm/redhat/zfs-dkms.spec.in
rpm/redhat/zfs.spec.in
scripts/zloop.sh
tests/runfiles/linux.run
tests/zfs-tests/include/libtest.shlib
tests/zfs-tests/tests/functional/cli_root/zpool_clear/zpool_clear_001_pos.ksh
tests/zfs-tests/tests/functional/cli_root/zpool_upgrade/zpool_upgrade.kshlib
tests/zfs-tests/tests/functional/cli_root/zpool_upgrade/zpool_upgrade_004_pos.ksh
tests/zfs-tests/tests/functional/features/async_destroy/async_destroy_001_pos.ksh
tests/zfs-tests/tests/functional/rsend/Makefile.am
tests/zfs-tests/tests/functional/rsend/Makefile.in
tests/zfs-tests/tests/functional/rsend/rsend.kshlib
tests/zfs-tests/tests/functional/rsend/rsend_019_pos.ksh
tests/zfs-tests/tests/functional/rsend/rsend_020_pos.ksh
tests/zfs-tests/tests/functional/rsend/rsend_021_pos.ksh
tests/zfs-tests/tests/functional/rsend/rsend_022_pos.ksh
tests/zfs-tests/tests/functional/rsend/rsend_024_pos.ksh
tests/zfs-tests/tests/functional/rsend/send-c_resume.ksh
tests/zfs-tests/tests/functional/rsend/send_freeobjects.ksh [new file with mode: 0755]

diff --git a/META b/META
index fbf7ae5644cd8f802c7615af0e06d11859ae8e37..491172577a1758d02244b8f62e7e580fba0cb4c2 100644 (file)
--- a/META
+++ b/META
@@ -1,7 +1,7 @@
 Meta:         1
 Name:         zfs
 Branch:       1.0
-Version:      0.7.2
+Version:      0.7.3
 Release:      1
 Release-Tags: relext
 License:      CDDL
index b1b7994b7cec36ca4cec601aeb6032105c2f34c6..e46ac2dbe5aaf9e654666f430fa074b502abab09 100644 (file)
@@ -92,5 +92,6 @@ etags:
 tags: ctags etags
 
 pkg: @DEFAULT_PACKAGE@
+pkg-dkms: @DEFAULT_PACKAGE@-dkms
 pkg-kmod: @DEFAULT_PACKAGE@-kmod
 pkg-utils: @DEFAULT_PACKAGE@-utils
index 0816325af6562a03969a9760cba9893b1bb36c9f..f40b3052576b83e7498eeab15ad69bfba81c88d6 100644 (file)
@@ -1136,42 +1136,50 @@ deb-local:
        fi)
 
 deb-kmod: deb-local rpm-kmod
-@CONFIG_KERNEL_TRUE@   name=${PACKAGE}; \
-@CONFIG_KERNEL_TRUE@   version=${VERSION}-${RELEASE}; \
-@CONFIG_KERNEL_TRUE@   arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
-@CONFIG_KERNEL_TRUE@   pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
-@CONFIG_KERNEL_TRUE@   fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
-@CONFIG_KERNEL_TRUE@   $(RM) $$pkg1
+       name=${PACKAGE}; \
+       version=${VERSION}-${RELEASE}; \
+       arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       $(RM) $$pkg1
+
+deb-dkms: deb-local rpm-dkms
+       name=${PACKAGE}; \
+       version=${VERSION}-${RELEASE}; \
+       arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       $(RM) $$pkg1
 
 deb-utils: deb-local rpm-utils
-@CONFIG_USER_TRUE@     name=${PACKAGE}; \
-@CONFIG_USER_TRUE@     version=${VERSION}-${RELEASE}; \
-@CONFIG_USER_TRUE@     arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
-@CONFIG_USER_TRUE@     pkg1=$${name}-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg2=libnvpair1-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg3=libuutil1-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg4=libzfs2-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg5=libzpool2-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg7=$${name}-test-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg8=$${name}-dracut-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
-@CONFIG_USER_TRUE@     path_prepend=`mktemp -d /tmp/intercept.XXX`; \
-@CONFIG_USER_TRUE@     echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
-@CONFIG_USER_TRUE@     echo "`which dh_shlibdeps` -- \
-@CONFIG_USER_TRUE@      -xlibuutil1linux -xlibnvpair1linux -xlibzfs2linux -xlibzpool2linux" \
-@CONFIG_USER_TRUE@      >> $${path_prepend}/dh_shlibdeps; \
-@CONFIG_USER_TRUE@     chmod +x $${path_prepend}/dh_shlibdeps; \
-@CONFIG_USER_TRUE@     env PATH=$${path_prepend}:$${PATH} \
-@CONFIG_USER_TRUE@     fakeroot $(ALIEN) --bump=0 --scripts --to-deb \
-@CONFIG_USER_TRUE@         $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
-@CONFIG_USER_TRUE@         $$pkg8 $$pkg9; \
-@CONFIG_USER_TRUE@     $(RM) $${path_prepend}/dh_shlibdeps; \
-@CONFIG_USER_TRUE@     rmdir $${path_prepend}; \
-@CONFIG_USER_TRUE@     $(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
-@CONFIG_USER_TRUE@         $$pkg8 $$pkg9;
-
-deb: deb-kmod deb-utils
+       name=${PACKAGE}; \
+       version=${VERSION}-${RELEASE}; \
+       arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       pkg1=$${name}-$${version}.$${arch}.rpm; \
+       pkg2=libnvpair1-$${version}.$${arch}.rpm; \
+       pkg3=libuutil1-$${version}.$${arch}.rpm; \
+       pkg4=libzfs2-$${version}.$${arch}.rpm; \
+       pkg5=libzpool2-$${version}.$${arch}.rpm; \
+       pkg6=libzfs2-devel-$${version}.$${arch}.rpm; \
+       pkg7=$${name}-test-$${version}.$${arch}.rpm; \
+       pkg8=$${name}-dracut-$${version}.$${arch}.rpm; \
+       pkg9=$${name}-initramfs-$${version}.$${arch}.rpm; \
+       path_prepend=`mktemp -d /tmp/intercept.XXX`; \
+       echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
+       echo "`which dh_shlibdeps` -- \
+        -xlibuutil1linux -xlibnvpair1linux -xlibzfs2linux -xlibzpool2linux" \
+        >> $${path_prepend}/dh_shlibdeps; \
+       chmod +x $${path_prepend}/dh_shlibdeps; \
+       env PATH=$${path_prepend}:$${PATH} \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb \
+           $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
+           $$pkg8 $$pkg9; \
+       $(RM) $${path_prepend}/dh_shlibdeps; \
+       rmdir $${path_prepend}; \
+       $(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
+           $$pkg8 $$pkg9;
+
+deb: deb-kmod deb-dkms deb-utils
 tgz-local:
        @(if test "${HAVE_ALIEN}" = "no"; then \
                echo -e "\n" \
@@ -1270,6 +1278,7 @@ etags:
 tags: ctags etags
 
 pkg: @DEFAULT_PACKAGE@
+pkg-dkms: @DEFAULT_PACKAGE@-dkms
 pkg-kmod: @DEFAULT_PACKAGE@-kmod
 pkg-utils: @DEFAULT_PACKAGE@-utils
 
index a79fe862d97a9c144d5b8a065a992fbe157780e6..5b27f1e4f1f248531f7af9b5113577da6fc38e9e 100644 (file)
@@ -394,13 +394,13 @@ zed_conf_scan_dir(struct zed_conf *zcp)
                            direntp->d_name);
                        continue;
                }
-               if ((st.st_mode & S_IWGRP) & !zcp->do_force) {
+               if ((st.st_mode & S_IWGRP) && !zcp->do_force) {
                        zed_log_msg(LOG_NOTICE,
                            "Ignoring \"%s\": writable by group",
                            direntp->d_name);
                        continue;
                }
-               if ((st.st_mode & S_IWOTH) & !zcp->do_force) {
+               if ((st.st_mode & S_IWOTH) && !zcp->do_force) {
                        zed_log_msg(LOG_NOTICE,
                            "Ignoring \"%s\": writable by other",
                            direntp->d_name);
index 6665e4a2d408bd455f06a44a7b341cc45a701410..98e98e45f40233fd2bb142107ccd78c81e827e5a 100644 (file)
@@ -15,17 +15,23 @@ deb-local:
        fi)
 
 deb-kmod: deb-local rpm-kmod
-if CONFIG_KERNEL
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
        pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
        fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
        $(RM) $$pkg1
-endif
+
+
+deb-dkms: deb-local rpm-dkms
+       name=${PACKAGE}; \
+       version=${VERSION}-${RELEASE}; \
+       arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       $(RM) $$pkg1
 
 deb-utils: deb-local rpm-utils
-if CONFIG_USER
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
@@ -58,6 +64,5 @@ if CONFIG_USER
        rmdir $${path_prepend}; \
        $(RM) $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
            $$pkg8 $$pkg9;
-endif
 
-deb: deb-kmod deb-utils
+deb: deb-kmod deb-dkms deb-utils
index a824c07ab762e7810731130b5ca4b86d0f37aa8d..448e4821e650ff1a0002f4eeeaae1ace18303ca7 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for zfs 0.7.2.
+# Generated by GNU Autoconf 2.63 for zfs 0.7.3.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='zfs'
 PACKAGE_TARNAME='zfs'
-PACKAGE_VERSION='0.7.2'
-PACKAGE_STRING='zfs 0.7.2'
+PACKAGE_VERSION='0.7.3'
+PACKAGE_STRING='zfs 0.7.3'
 PACKAGE_BUGREPORT=''
 
 # Factoring default headers for most tests.
@@ -1599,7 +1599,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures zfs 0.7.2 to adapt to many kinds of systems.
+\`configure' configures zfs 0.7.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1670,7 +1670,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of zfs 0.7.2:";;
+     short | recursive ) echo "Configuration of zfs 0.7.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1804,7 +1804,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-zfs configure 0.7.2
+zfs configure 0.7.3
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1818,7 +1818,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by zfs $as_me 0.7.2, which was
+It was created by zfs $as_me 0.7.3, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
@@ -2976,7 +2976,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='zfs'
- VERSION='0.7.2'
+ VERSION='0.7.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -46174,7 +46174,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by zfs $as_me 0.7.2, which was
+This file was extended by zfs $as_me 0.7.3, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -46237,7 +46237,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-zfs config.status 0.7.2
+zfs config.status 0.7.3
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index 9bbee0e5740c14fd4d0319a25684b65bbf4d5391..08aeac2d712bb306906fc3f99bcab1cc96443172 100755 (executable)
@@ -46,6 +46,9 @@ install() {
                # On systems with gcc-config (Gentoo, Funtoo, etc.):
                # Use the current profile to resolve the appropriate path
                dracut_install "/usr/lib/gcc/$(s=$(gcc-config -c); echo ${s%-*}/${s##*-})/libgcc_s.so.1"
+       elif [[ -n "$(ls /usr/lib/libgcc_s.so* 2>/dev/null)" ]]; then
+               # Try a simple path first
+               dracut_install /usr/lib/libgcc_s.so*
        else
                # Fallback: Guess the path and include all matches
                dracut_install /usr/lib/gcc/*/*/libgcc_s.so*
index dd796b6ff3a7ba860e51b733c280bf033c3e8294..26aaa6e186f0d59f6611533b7f29088323e70cfd 100755 (executable)
@@ -19,7 +19,7 @@ COPY_EXEC_LIST="$COPY_EXEC_LIST /bin/hostname /sbin/blkid"
 
 # Explicitly specify all kernel modules because automatic dependency resolution
 # is unreliable on many systems.
-BASE_MODULES="zlib_deflate spl zavl zcommon znvpair zunicode zfs"
+BASE_MODULES="zlib_deflate spl zavl zcommon znvpair zunicode zfs icp"
 CRPT_MODULES="sun-ccm sun-gcm sun-ctr"
 MANUAL_ADD_MODULES_LIST="$BASE_MODULES"
 
index f09b2c81ba29d4cba5b83d87da1008261b6b1e89..e8e5cd26451cbc0a6995c275c7c3bf0476ec1478 100755 (executable)
@@ -44,7 +44,7 @@ activate_vg()
 {
         # Sanity checks
         if [ ! -x /sbin/lvm ]; then
-                message "lvm is not available"
+                [ "$quiet" != "y" ] && message "lvm is not available"
                 return 1
         fi
 
index 68373d2f290e144ce94af39391687b45cd41655d..4650c964655b9a6e9beff50bf25a4fd0b7ea8cd6 100644 (file)
@@ -579,10 +579,10 @@ ask_user_snap()
            eval `echo SNAP_$i=$snap`
            i=$((i + 1))
        done <<EOT
-$("${ZFS}" list -H -oname -tsnapshot "${fs}")
+$("${ZFS}" list -H -oname -tsnapshot -r "${fs}")
 EOT
 
-       echo -n "  Snap nr [0-$((i-1))]? " > /dev/stderr
+       echo -n "  Snap nr [1-$((i-1))]? " > /dev/stderr
        read snapnr
 
        # Re-enable debugging.
index 07a72302df7b19c6b89005e692706cb8f02d0f50..66f37cf7102584295c8a068830ae716c817bf705 100644 (file)
@@ -248,7 +248,7 @@ void arc_flush(spa_t *spa, boolean_t retry);
 void arc_tempreserve_clear(uint64_t reserve);
 int arc_tempreserve_space(uint64_t reserve, uint64_t txg);
 
-uint64_t arc_max_bytes(void);
+uint64_t arc_target_bytes(void);
 void arc_init(void);
 void arc_fini(void);
 
index e9bef8bddb736e7bcdc9b0f0d9c26ffadb3c6570..5cf67a6ab580cbd1c841c3b3ca171024f1ac40ed 100644 (file)
@@ -61,6 +61,7 @@ typedef struct dmu_recv_cookie {
        boolean_t drc_byteswap;
        boolean_t drc_force;
        boolean_t drc_resumable;
+       boolean_t drc_clone;
        struct avl_tree *drc_guid_to_ds_map;
        zio_cksum_t drc_cksum;
        uint64_t drc_newsnapobj;
index 50c1e9337f5b6f8da83ebad82a130a62ffb2dfe1..1281674bbec23e418835859536eba378dff8c92c 100644 (file)
@@ -279,8 +279,8 @@ spa_t *dsl_dataset_get_spa(dsl_dataset_t *ds);
 boolean_t dsl_dataset_modified_since_snap(dsl_dataset_t *ds,
     dsl_dataset_t *snap);
 
-void dsl_dataset_sync(dsl_dataset_t *os, zio_t *zio, dmu_tx_t *tx);
-void dsl_dataset_sync_done(dsl_dataset_t *os, dmu_tx_t *tx);
+void dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx);
+void dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx);
 
 void dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp,
     dmu_tx_t *tx);
@@ -290,7 +290,7 @@ int dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name,
     uint64_t *value);
 
 void dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx);
-void dsl_dataset_stats(dsl_dataset_t *os, nvlist_t *nv);
+void dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv);
 void dsl_dataset_fast_stat(dsl_dataset_t *ds, dmu_objset_stats_t *stat);
 void dsl_dataset_space(dsl_dataset_t *ds,
     uint64_t *refdbytesp, uint64_t *availbytesp,
index 3c99529f1aae375285ccd68f9a42cec1a04a5636..59bc8ffb42fbf4cc304e79fc54aa724d67184ad1 100644 (file)
@@ -13,7 +13,7 @@ DEFAULT_INCLUDES += \
        -I$(top_srcdir)/lib/libspl/include
 
 AM_CCASFLAGS = \
-       -I$(top_srcdir)/lib/libspl/include
+       $(CFLAGS)
 
 noinst_LTLIBRARIES = libspl.la
 
index 7e053b9cf891e5a20f097727222012b89a979cd8..6fd079b0d54a14a97b900037ab454c4d040fd16e 100644 (file)
@@ -464,7 +464,7 @@ AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT \
 SUBDIRS = include $(TARGET_ASM_DIR)
 DIST_SUBDIRS = include asm-generic asm-i386 asm-x86_64
 AM_CCASFLAGS = \
-       -I$(top_srcdir)/lib/libspl/include
+       $(CFLAGS)
 
 noinst_LTLIBRARIES = libspl.la
 USER_C = \
index 9244ada529f40f6513e8d30983dbae96f6163d1c..c5190f786597b56163dee3683439651d4a1ea440 100644 (file)
@@ -5,7 +5,7 @@ includedir=${prefix}/include
 
 Name: libzfs
 Description: LibZFS library
-Version: 0.7.2
+Version: 0.7.3
 URL: http://zfsonlinux.org
 Requires: libzfs_core
 Cflags: -I${includedir}/libzfs -I${includedir}/libspl
index 6ab9307eb01f7cf31482fe266db0119df75e6c7c..30fe3745125122f03c023bd1081149b2a97f5960 100644 (file)
@@ -5,7 +5,7 @@ includedir=${prefix}/include
 
 Name: libzfs_core
 Description: LibZFS core library
-Version: 0.7.2
+Version: 0.7.3
 URL: http://zfsonlinux.org
 Cflags: -I${includedir}/libzfs -I${includedir}/libspl
 Libs: -L${libdir} -lzfs_core
index f371d925bc59c4223089260bcb482fdc0700035b..8b52224758da034401995b5e5aad527ac3ca35c2 100644 (file)
@@ -2297,7 +2297,7 @@ find_aux(zpool_handle_t *zhp, void *data)
 
 /*
  * Determines if the pool is in use.  If so, it returns true and the state of
- * the pool as well as the name of the pool.  Both strings are allocated and
+ * the pool as well as the name of the pool.  Name string is allocated and
  * must be freed by the caller.
  */
 int
index 57ebdd89d1b8e562cc092c85248ef41305ae3a0d..75267d05368c83ac84eda1ec895abdc6545e7439 100644 (file)
@@ -428,10 +428,10 @@ zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
 {
        int ret;
 
-       if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
+       if ((ret = zfs_iter_snapshots(zhp, B_FALSE, func, data)) != 0)
                return (ret);
 
-       return (zfs_iter_snapshots(zhp, B_FALSE, func, data));
+       return (zfs_iter_filesystems(zhp, func, data));
 }
 
 
index ff909f1e35740674d11e7e3dcd83fff74402872b..db8079fb3ec60558638cb55d466c4a2415453054 100644 (file)
@@ -1609,6 +1609,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
        int error = 0;
        char name[ZFS_MAX_DATASET_NAME_LEN];
        enum lzc_send_flags lzc_flags = 0;
+       FILE *fout = (flags->verbose && flags->dryrun) ? stdout : stderr;
 
        (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
            "cannot resume send"));
@@ -1623,9 +1624,9 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
                return (zfs_error(hdl, EZFS_FAULT, errbuf));
        }
        if (flags->verbose) {
-               (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+               (void) fprintf(fout, dgettext(TEXT_DOMAIN,
                    "resume token contents:\n"));
-               nvlist_print(stderr, resume_nvl);
+               nvlist_print(fout, resume_nvl);
        }
 
        if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 ||
@@ -1682,7 +1683,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
                    lzc_flags, &size);
                if (error == 0)
                        size = MAX(0, (int64_t)(size - bytes));
-               send_print_verbose(stderr, zhp->zfs_name, fromname,
+               send_print_verbose(fout, zhp->zfs_name, fromname,
                    size, flags->parsable);
        }
 
index b826c54ade7bc079ca8d8ac96edeaddce38f27eb..7f28b3796b5d5c01aed99c81f2c45d5c85467de4 100644 (file)
 
 static void Encode(uint8_t *, const uint32_t *, size_t);
 
-#if    defined(__amd64)
+#if    defined(__sparc)
+
+#define        SHA1_TRANSFORM(ctx, in) \
+       SHA1Transform((ctx)->state[0], (ctx)->state[1], (ctx)->state[2], \
+               (ctx)->state[3], (ctx)->state[4], (ctx), (in))
+
+static void SHA1Transform(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,
+       SHA1_CTX *, const uint8_t *);
+
+#elif  defined(__amd64)
 
 #define        SHA1_TRANSFORM(ctx, in) sha1_block_data_order((ctx), (in), 1)
 #define        SHA1_TRANSFORM_BLOCKS(ctx, in, num) sha1_block_data_order((ctx), \
@@ -260,6 +269,158 @@ typedef uint32_t sha1word;
 #define        W(n) w_ ## n
 #endif /* !defined(W_ARRAY) */
 
+#if    defined(__sparc)
+
+
+/*
+ * sparc register window optimization:
+ *
+ * `a', `b', `c', `d', and `e' are passed into SHA1Transform
+ * explicitly since it increases the number of registers available to
+ * the compiler.  under this scheme, these variables can be held in
+ * %i0 - %i4, which leaves more local and out registers available.
+ *
+ * purpose: sha1 transformation -- updates the digest based on `block'
+ *   input: uint32_t   : bytes  1 -  4 of the digest
+ *          uint32_t   : bytes  5 -  8 of the digest
+ *          uint32_t   : bytes  9 - 12 of the digest
+ *          uint32_t   : bytes 12 - 16 of the digest
+ *          uint32_t   : bytes 16 - 20 of the digest
+ *          SHA1_CTX * : the context to update
+ *          uint8_t [64]: the block to use to update the digest
+ *  output: void
+ */
+
+
+void
+SHA1Transform(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
+    SHA1_CTX *ctx, const uint8_t blk[64])
+{
+       /*
+        * sparc optimization:
+        *
+        * while it is somewhat counter-intuitive, on sparc, it is
+        * more efficient to place all the constants used in this
+        * function in an array and load the values out of the array
+        * than to manually load the constants.  this is because
+        * setting a register to a 32-bit value takes two ops in most
+        * cases: a `sethi' and an `or', but loading a 32-bit value
+        * from memory only takes one `ld' (or `lduw' on v9).  while
+        * this increases memory usage, the compiler can find enough
+        * other things to do while waiting to keep the pipeline does
+        * not stall.  additionally, it is likely that many of these
+        * constants are cached so that later accesses do not even go
+        * out to the bus.
+        *
+        * this array is declared `static' to keep the compiler from
+        * having to bcopy() this array onto the stack frame of
+        * SHA1Transform() each time it is called -- which is
+        * unacceptably expensive.
+        *
+        * the `const' is to ensure that callers are good citizens and
+        * do not try to munge the array.  since these routines are
+        * going to be called from inside multithreaded kernelland,
+        * this is a good safety check. -- `sha1_consts' will end up in
+        * .rodata.
+        *
+        * unfortunately, loading from an array in this manner hurts
+        * performance under Intel.  So, there is a macro,
+        * SHA1_CONST(), used in SHA1Transform(), that either expands to
+        * a reference to this array, or to the actual constant,
+        * depending on what platform this code is compiled for.
+        */
+
+
+       static const uint32_t sha1_consts[] = {
+               SHA1_CONST_0, SHA1_CONST_1, SHA1_CONST_2, SHA1_CONST_3
+       };
+
+
+       /*
+        * general optimization:
+        *
+        * use individual integers instead of using an array.  this is a
+        * win, although the amount it wins by seems to vary quite a bit.
+        */
+
+
+       uint32_t        w_0, w_1, w_2,  w_3,  w_4,  w_5,  w_6,  w_7;
+       uint32_t        w_8, w_9, w_10, w_11, w_12, w_13, w_14, w_15;
+
+
+       /*
+        * sparc optimization:
+        *
+        * if `block' is already aligned on a 4-byte boundary, use
+        * LOAD_BIG_32() directly.  otherwise, bcopy() into a
+        * buffer that *is* aligned on a 4-byte boundary and then do
+        * the LOAD_BIG_32() on that buffer.  benchmarks have shown
+        * that using the bcopy() is better than loading the bytes
+        * individually and doing the endian-swap by hand.
+        *
+        * even though it's quite tempting to assign to do:
+        *
+        * blk = bcopy(ctx->buf_un.buf32, blk, sizeof (ctx->buf_un.buf32));
+        *
+        * and only have one set of LOAD_BIG_32()'s, the compiler
+        * *does not* like that, so please resist the urge.
+        */
+
+
+       if ((uintptr_t)blk & 0x3) {             /* not 4-byte aligned? */
+               bcopy(blk, ctx->buf_un.buf32,  sizeof (ctx->buf_un.buf32));
+               w_15 = LOAD_BIG_32(ctx->buf_un.buf32 + 15);
+               w_14 = LOAD_BIG_32(ctx->buf_un.buf32 + 14);
+               w_13 = LOAD_BIG_32(ctx->buf_un.buf32 + 13);
+               w_12 = LOAD_BIG_32(ctx->buf_un.buf32 + 12);
+               w_11 = LOAD_BIG_32(ctx->buf_un.buf32 + 11);
+               w_10 = LOAD_BIG_32(ctx->buf_un.buf32 + 10);
+               w_9  = LOAD_BIG_32(ctx->buf_un.buf32 +  9);
+               w_8  = LOAD_BIG_32(ctx->buf_un.buf32 +  8);
+               w_7  = LOAD_BIG_32(ctx->buf_un.buf32 +  7);
+               w_6  = LOAD_BIG_32(ctx->buf_un.buf32 +  6);
+               w_5  = LOAD_BIG_32(ctx->buf_un.buf32 +  5);
+               w_4  = LOAD_BIG_32(ctx->buf_un.buf32 +  4);
+               w_3  = LOAD_BIG_32(ctx->buf_un.buf32 +  3);
+               w_2  = LOAD_BIG_32(ctx->buf_un.buf32 +  2);
+               w_1  = LOAD_BIG_32(ctx->buf_un.buf32 +  1);
+               w_0  = LOAD_BIG_32(ctx->buf_un.buf32 +  0);
+       } else {
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_15 = LOAD_BIG_32(blk + 60);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_14 = LOAD_BIG_32(blk + 56);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_13 = LOAD_BIG_32(blk + 52);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_12 = LOAD_BIG_32(blk + 48);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_11 = LOAD_BIG_32(blk + 44);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_10 = LOAD_BIG_32(blk + 40);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_9  = LOAD_BIG_32(blk + 36);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_8  = LOAD_BIG_32(blk + 32);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_7  = LOAD_BIG_32(blk + 28);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_6  = LOAD_BIG_32(blk + 24);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_5  = LOAD_BIG_32(blk + 20);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_4  = LOAD_BIG_32(blk + 16);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_3  = LOAD_BIG_32(blk + 12);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_2  = LOAD_BIG_32(blk +  8);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_1  = LOAD_BIG_32(blk +  4);
+               /* LINTED E_BAD_PTR_CAST_ALIGN */
+               w_0  = LOAD_BIG_32(blk +  0);
+       }
+#else  /* !defined(__sparc) */
+
 void /* CSTYLED */
 SHA1Transform(SHA1_CTX *ctx, const uint8_t blk[64])
 {
@@ -294,6 +455,8 @@ SHA1Transform(SHA1_CTX *ctx, const uint8_t blk[64])
        W(14) = LOAD_BIG_32((void *)(blk + 56));
        W(15) = LOAD_BIG_32((void *)(blk + 60));
 
+#endif /* !defined(__sparc) */
+
        /*
         * general optimization:
         *
@@ -654,10 +817,22 @@ Encode(uint8_t *_RESTRICT_KYWD output, const uint32_t *_RESTRICT_KYWD input,
 {
        size_t          i, j;
 
-       for (i = 0, j = 0; j < len; i++, j += 4) {
-               output[j]       = (input[i] >> 24) & 0xff;
-               output[j + 1]   = (input[i] >> 16) & 0xff;
-               output[j + 2]   = (input[i] >>  8) & 0xff;
-               output[j + 3]   = input[i] & 0xff;
+#if defined(__sparc)
+       if (IS_P2ALIGNED(output, sizeof (uint32_t))) {
+               for (i = 0, j = 0; j < len; i++, j += 4) {
+                       /* LINTED E_BAD_PTR_CAST_ALIGN */
+                       *((uint32_t *)(output + j)) = input[i];
+               }
+       } else {
+#endif /* little endian -- will work on big endian, but slowly */
+
+               for (i = 0, j = 0; j < len; i++, j += 4) {
+                       output[j]       = (input[i] >> 24) & 0xff;
+                       output[j + 1]   = (input[i] >> 16) & 0xff;
+                       output[j + 2]   = (input[i] >>  8) & 0xff;
+                       output[j + 3]   = input[i] & 0xff;
+               }
+#if defined(__sparc)
        }
+#endif
 }
index 0a09c443b0dcffe76d40c8e9f3e1265daa8bdeff..48950245e295fc723e266d0ff7d32a9de52b4595 100644 (file)
@@ -632,6 +632,9 @@ typedef struct arc_stats {
        kstat_named_t arcstat_memory_throttle_count;
        kstat_named_t arcstat_memory_direct_count;
        kstat_named_t arcstat_memory_indirect_count;
+       kstat_named_t arcstat_memory_all_bytes;
+       kstat_named_t arcstat_memory_free_bytes;
+       kstat_named_t arcstat_memory_available_bytes;
        kstat_named_t arcstat_no_grow;
        kstat_named_t arcstat_tempreserve;
        kstat_named_t arcstat_loaned_bytes;
@@ -727,6 +730,9 @@ static arc_stats_t arc_stats = {
        { "memory_throttle_count",      KSTAT_DATA_UINT64 },
        { "memory_direct_count",        KSTAT_DATA_UINT64 },
        { "memory_indirect_count",      KSTAT_DATA_UINT64 },
+       { "memory_all_bytes",           KSTAT_DATA_UINT64 },
+       { "memory_free_bytes",          KSTAT_DATA_UINT64 },
+       { "memory_available_bytes",     KSTAT_DATA_INT64 },
        { "arc_no_grow",                KSTAT_DATA_UINT64 },
        { "arc_tempreserve",            KSTAT_DATA_UINT64 },
        { "arc_loaned_bytes",           KSTAT_DATA_UINT64 },
@@ -3981,30 +3987,46 @@ static uint64_t
 arc_all_memory(void)
 {
 #ifdef _KERNEL
-       return (MIN(ptob(physmem),
-           vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)));
+#ifdef CONFIG_HIGHMEM
+       return (ptob(totalram_pages - totalhigh_pages));
+#else
+       return (ptob(totalram_pages));
+#endif /* CONFIG_HIGHMEM */
 #else
        return (ptob(physmem) / 2);
-#endif
+#endif /* _KERNEL */
 }
 
-#ifdef _KERNEL
+/*
+ * Return the amount of memory that is considered free.  In user space
+ * which is primarily used for testing we pretend that free memory ranges
+ * from 0-20% of all memory.
+ */
 static uint64_t
 arc_free_memory(void)
 {
+#ifdef _KERNEL
+#ifdef CONFIG_HIGHMEM
+       struct sysinfo si;
+       si_meminfo(&si);
+       return (ptob(si.freeram - si.freehigh));
+#else
 #ifdef ZFS_GLOBAL_NODE_PAGE_STATE
-       return (nr_free_pages() +
+       return (ptob(nr_free_pages() +
            global_node_page_state(NR_INACTIVE_FILE) +
            global_node_page_state(NR_INACTIVE_ANON) +
-           global_node_page_state(NR_SLAB_RECLAIMABLE));
+           global_node_page_state(NR_SLAB_RECLAIMABLE)));
 #else
-       return (nr_free_pages() +
+       return (ptob(nr_free_pages() +
            global_page_state(NR_INACTIVE_FILE) +
            global_page_state(NR_INACTIVE_ANON) +
-           global_page_state(NR_SLAB_RECLAIMABLE));
-#endif
+           global_page_state(NR_SLAB_RECLAIMABLE)));
+#endif /* ZFS_GLOBAL_NODE_PAGE_STATE */
+#endif /* CONFIG_HIGHMEM */
+#else
+       return (spa_get_random(arc_all_memory() * 20 / 100));
+#endif /* _KERNEL */
 }
-#endif
 
 typedef enum free_memory_reason_t {
        FMR_UNKNOWN,
@@ -4042,17 +4064,15 @@ arc_available_memory(void)
        int64_t lowest = INT64_MAX;
        free_memory_reason_t r = FMR_UNKNOWN;
 #ifdef _KERNEL
-       uint64_t available_memory = ptob(arc_free_memory());
        int64_t n;
 #ifdef __linux__
+#ifdef freemem
+#undef freemem
+#endif
        pgcnt_t needfree = btop(arc_need_free);
        pgcnt_t lotsfree = btop(arc_sys_free);
        pgcnt_t desfree = 0;
-#endif
-
-#if defined(__i386)
-       available_memory =
-           MIN(available_memory, vmem_size(heap_arena, VMEM_FREE));
+       pgcnt_t freemem = btop(arc_free_memory());
 #endif
 
        if (needfree > 0) {
@@ -4070,7 +4090,7 @@ arc_available_memory(void)
         * number of needed free pages.  We add extra pages here to make sure
         * the scanner doesn't start up while we're freeing memory.
         */
-       n = PAGESIZE * (btop(available_memory) - lotsfree - needfree - desfree);
+       n = PAGESIZE * (freemem - lotsfree - needfree - desfree);
        if (n < lowest) {
                lowest = n;
                r = FMR_LOTSFREE;
@@ -4091,7 +4111,6 @@ arc_available_memory(void)
                r = FMR_SWAPFS_MINFREE;
        }
 
-
        /*
         * Check that we have enough availrmem that memory locking (e.g., via
         * mlock(3C) or memcntl(2)) can still succeed.  (pages_pp_maximum
@@ -4107,9 +4126,9 @@ arc_available_memory(void)
        }
 #endif
 
-#if defined(__i386)
+#if defined(_ILP32)
        /*
-        * If we're on an i386 platform, it's possible that we'll exhaust the
+        * If we're on a 32-bit platform, it's possible that we'll exhaust the
         * kernel heap space before we ever run out of available physical
         * memory.  Most checks of the size of the heap_area compare against
         * tune.t_minarmem, which is the minimum available real memory that we
@@ -4178,6 +4197,7 @@ arc_kmem_reap_now(void)
        extern kmem_cache_t     *zio_data_buf_cache[];
        extern kmem_cache_t     *range_seg_cache;
 
+#ifdef _KERNEL
        if ((arc_meta_used >= arc_meta_limit) && zfs_arc_meta_prune) {
                /*
                 * We are exceeding our meta-data cache limit.
@@ -4185,9 +4205,16 @@ arc_kmem_reap_now(void)
                 */
                arc_prune_async(zfs_arc_meta_prune);
        }
+#if defined(_ILP32)
+       /*
+        * Reclaim unused memory from all kmem caches.
+        */
+       kmem_reap();
+#endif
+#endif
 
        for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) {
-#ifdef _ILP32
+#if defined(_ILP32)
                /* reach upper limit of cache size on 32-bit */
                if (zio_buf_cache[i] == NULL)
                        break;
@@ -6077,14 +6104,11 @@ static int
 arc_memory_throttle(uint64_t reserve, uint64_t txg)
 {
 #ifdef _KERNEL
-       uint64_t available_memory = ptob(arc_free_memory());
+       uint64_t available_memory = arc_free_memory();
        static uint64_t page_load = 0;
        static uint64_t last_txg = 0;
-#ifdef __linux__
-       pgcnt_t minfree = btop(arc_sys_free / 4);
-#endif
 
-#if defined(__i386)
+#if defined(_ILP32)
        available_memory =
            MIN(available_memory, vmem_size(heap_arena, VMEM_FREE));
 #endif
@@ -6102,7 +6126,7 @@ arc_memory_throttle(uint64_t reserve, uint64_t txg)
         * continue to let page writes occur as quickly as possible.
         */
        if (current_is_kswapd()) {
-               if (page_load > MAX(ptob(minfree), available_memory) / 4) {
+               if (page_load > MAX(arc_sys_free / 4, available_memory) / 4) {
                        DMU_TX_STAT_BUMP(dmu_tx_memory_reclaim);
                        return (SET_ERROR(ERESTART));
                }
@@ -6232,6 +6256,13 @@ arc_kstat_update(kstat_t *ksp, int rw)
                    &as->arcstat_mfu_ghost_size,
                    &as->arcstat_mfu_ghost_evictable_data,
                    &as->arcstat_mfu_ghost_evictable_metadata);
+
+               as->arcstat_memory_all_bytes.value.ui64 =
+                   arc_all_memory();
+               as->arcstat_memory_free_bytes.value.ui64 =
+                   arc_free_memory();
+               as->arcstat_memory_available_bytes.value.i64 =
+                   arc_available_memory();
        }
 
        return (0);
@@ -6475,9 +6506,9 @@ arc_state_fini(void)
 }
 
 uint64_t
-arc_max_bytes(void)
+arc_target_bytes(void)
 {
-       return (arc_c_max);
+       return (arc_c);
 }
 
 void
index dc2c00495b54c550668584815802659f8b08441e..62340469d3575b089fee6145fedf4201f733ce23 100644 (file)
@@ -464,24 +464,35 @@ dbuf_cache_multilist_index_func(multilist_t *ml, void *obj)
            multilist_get_num_sublists(ml));
 }
 
+static inline unsigned long
+dbuf_cache_target_bytes(void)
+{
+       return MIN(dbuf_cache_max_bytes,
+           arc_target_bytes() >> dbuf_cache_max_shift);
+}
+
 static inline boolean_t
 dbuf_cache_above_hiwater(void)
 {
+       uint64_t dbuf_cache_target = dbuf_cache_target_bytes();
+
        uint64_t dbuf_cache_hiwater_bytes =
-           (dbuf_cache_max_bytes * dbuf_cache_hiwater_pct) / 100;
+           (dbuf_cache_target * dbuf_cache_hiwater_pct) / 100;
 
        return (refcount_count(&dbuf_cache_size) >
-           dbuf_cache_max_bytes + dbuf_cache_hiwater_bytes);
+           dbuf_cache_target + dbuf_cache_hiwater_bytes);
 }
 
 static inline boolean_t
 dbuf_cache_above_lowater(void)
 {
+       uint64_t dbuf_cache_target = dbuf_cache_target_bytes();
+
        uint64_t dbuf_cache_lowater_bytes =
-           (dbuf_cache_max_bytes * dbuf_cache_lowater_pct) / 100;
+           (dbuf_cache_target * dbuf_cache_lowater_pct) / 100;
 
        return (refcount_count(&dbuf_cache_size) >
-           dbuf_cache_max_bytes - dbuf_cache_lowater_bytes);
+           dbuf_cache_target - dbuf_cache_lowater_bytes);
 }
 
 /*
@@ -601,7 +612,7 @@ dbuf_evict_notify(void)
         * because it's OK to occasionally make the wrong decision here,
         * and grabbing the lock results in massive lock contention.
         */
-       if (refcount_count(&dbuf_cache_size) > dbuf_cache_max_bytes) {
+       if (refcount_count(&dbuf_cache_size) > dbuf_cache_target_bytes()) {
                if (dbuf_cache_above_hiwater())
                        dbuf_evict_one();
                cv_signal(&dbuf_evict_cv);
@@ -658,7 +669,7 @@ retry:
         * dbuf cache to 1/32nd (default) of the size of the ARC.
         */
        dbuf_cache_max_bytes = MIN(dbuf_cache_max_bytes,
-           arc_max_bytes() >> dbuf_cache_max_shift);
+           arc_target_bytes() >> dbuf_cache_max_shift);
 
        /*
         * All entries are queued via taskq_dispatch_ent(), so min/maxalloc
index a2ace9be519f5b36c2e9b97baf48cb632924360b..344e42018df1f236c828497e2b74d00980c39ad3 100644 (file)
@@ -421,6 +421,22 @@ static int
 dump_freeobjects(dmu_sendarg_t *dsp, uint64_t firstobj, uint64_t numobjs)
 {
        struct drr_freeobjects *drrfo = &(dsp->dsa_drr->drr_u.drr_freeobjects);
+       uint64_t maxobj = DNODES_PER_BLOCK *
+           (DMU_META_DNODE(dsp->dsa_os)->dn_maxblkid + 1);
+
+       /*
+        * ZoL < 0.7 does not handle large FREEOBJECTS records correctly,
+        * leading to zfs recv never completing. to avoid this issue, don't
+        * send FREEOBJECTS records for object IDs which cannot exist on the
+        * receiving side.
+        */
+       if (maxobj > 0) {
+               if (maxobj < firstobj)
+                       return (0);
+
+               if (maxobj < firstobj + numobjs)
+                       numobjs = maxobj - firstobj;
+       }
 
        /*
         * If there is a pending op, but it's not PENDING_FREEOBJECTS,
@@ -1807,6 +1823,7 @@ dmu_recv_begin(char *tofs, char *tosnap, dmu_replay_record_t *drr_begin,
        drc->drc_force = force;
        drc->drc_resumable = resumable;
        drc->drc_cred = CRED();
+       drc->drc_clone = (origin != NULL);
 
        if (drc->drc_drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
                drc->drc_byteswap = B_TRUE;
@@ -1867,7 +1884,9 @@ struct receive_writer_arg {
        /* A map from guid to dataset to help handle dedup'd streams. */
        avl_tree_t *guid_to_ds_map;
        boolean_t resumable;
-       uint64_t last_object, last_offset;
+       uint64_t last_object;
+       uint64_t last_offset;
+       uint64_t max_object; /* highest object ID referenced in stream */
        uint64_t bytes_read; /* bytes read when current record created */
 };
 
@@ -2141,6 +2160,9 @@ receive_object(struct receive_writer_arg *rwa, struct drr_object *drro,
                return (SET_ERROR(EINVAL));
        object = err == 0 ? drro->drr_object : DMU_NEW_OBJECT;
 
+       if (drro->drr_object > rwa->max_object)
+               rwa->max_object = drro->drr_object;
+
        /*
         * If we are losing blkptrs or changing the block size this must
         * be a new file instance.  We must clear out the previous file
@@ -2233,16 +2255,17 @@ receive_freeobjects(struct receive_writer_arg *rwa,
                int err;
 
                err = dmu_object_info(rwa->os, obj, &doi);
-               if (err == ENOENT) {
-                       obj++;
+               if (err == ENOENT)
                        continue;
-               } else if (err != 0) {
+               else if (err != 0)
                        return (err);
-               }
 
                err = dmu_free_long_object(rwa->os, obj);
                if (err != 0)
                        return (err);
+
+               if (obj > rwa->max_object)
+                       rwa->max_object = obj;
        }
        if (next_err != ESRCH)
                return (next_err);
@@ -2273,6 +2296,9 @@ receive_write(struct receive_writer_arg *rwa, struct drr_write *drrw,
        rwa->last_object = drrw->drr_object;
        rwa->last_offset = drrw->drr_offset;
 
+       if (rwa->last_object > rwa->max_object)
+               rwa->max_object = rwa->last_object;
+
        if (dmu_object_info(rwa->os, drrw->drr_object, NULL) != 0)
                return (SET_ERROR(EINVAL));
 
@@ -2348,6 +2374,9 @@ receive_write_byref(struct receive_writer_arg *rwa,
                ref_os = rwa->os;
        }
 
+       if (drrwbr->drr_object > rwa->max_object)
+               rwa->max_object = drrwbr->drr_object;
+
        err = dmu_buf_hold(ref_os, drrwbr->drr_refobject,
            drrwbr->drr_refoffset, FTAG, &dbp, DMU_READ_PREFETCH);
        if (err != 0)
@@ -2390,6 +2419,9 @@ receive_write_embedded(struct receive_writer_arg *rwa,
        if (drrwe->drr_compression >= ZIO_COMPRESS_FUNCTIONS)
                return (EINVAL);
 
+       if (drrwe->drr_object > rwa->max_object)
+               rwa->max_object = drrwe->drr_object;
+
        tx = dmu_tx_create(rwa->os);
 
        dmu_tx_hold_write(tx, drrwe->drr_object,
@@ -2426,6 +2458,9 @@ receive_spill(struct receive_writer_arg *rwa, struct drr_spill *drrs,
        if (dmu_object_info(rwa->os, drrs->drr_object, NULL) != 0)
                return (SET_ERROR(EINVAL));
 
+       if (drrs->drr_object > rwa->max_object)
+               rwa->max_object = drrs->drr_object;
+
        VERIFY0(dmu_bonus_hold(rwa->os, drrs->drr_object, FTAG, &db));
        if ((err = dmu_spill_hold_by_bonus(db, FTAG, &db_spill)) != 0) {
                dmu_buf_rele(db, FTAG);
@@ -2470,6 +2505,9 @@ receive_free(struct receive_writer_arg *rwa, struct drr_free *drrf)
        if (dmu_object_info(rwa->os, drrf->drr_object, NULL) != 0)
                return (SET_ERROR(EINVAL));
 
+       if (drrf->drr_object > rwa->max_object)
+               rwa->max_object = drrf->drr_object;
+
        err = dmu_free_long_range(rwa->os, drrf->drr_object,
            drrf->drr_offset, drrf->drr_length);
 
@@ -3193,6 +3231,32 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, vnode_t *vp, offset_t *voffp,
        }
        mutex_exit(&rwa->mutex);
 
+       /*
+        * If we are receiving a full stream as a clone, all object IDs which
+        * are greater than the maximum ID referenced in the stream are
+        * by definition unused and must be freed.
+        */
+       if (drc->drc_clone && drc->drc_drrb->drr_fromguid == 0) {
+               uint64_t obj = rwa->max_object + 1;
+               int free_err = 0;
+               int next_err = 0;
+
+               while (next_err == 0) {
+                       free_err = dmu_free_long_object(rwa->os, obj);
+                       if (free_err != 0 && free_err != ENOENT)
+                               break;
+
+                       next_err = dmu_object_next(rwa->os, &obj, FALSE, 0);
+               }
+
+               if (err == 0) {
+                       if (free_err != 0 && free_err != ENOENT)
+                               err = free_err;
+                       else if (next_err != ESRCH)
+                               err = next_err;
+               }
+       }
+
        cv_destroy(&rwa->cv);
        mutex_destroy(&rwa->mutex);
        bqueue_destroy(&rwa->q);
index a0a02366e1d9074c0484598983ee6de4c2d34820..27e79ae60e3381d6c4087412467beeb1dd33eed3 100644 (file)
@@ -1164,7 +1164,7 @@ vdev_copy_uberblocks(vdev_t *vd)
 
        spa_config_enter(vd->vdev_spa, locks, FTAG, RW_READER);
 
-       ub_abd = abd_alloc(VDEV_UBERBLOCK_SIZE(vd), B_TRUE);
+       ub_abd = abd_alloc_linear(VDEV_UBERBLOCK_SIZE(vd), B_TRUE);
 
        write_zio = zio_root(vd->vdev_spa, NULL, NULL, flags);
        for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) {
index 259bfb3091320d2f22149311010d41bac8f364cd..a88f2482e722043e81cffe746b1786b1ecea8bd4 100644 (file)
@@ -4562,7 +4562,7 @@ convoff(struct inode *ip, flock64_t *lckdat, int  whence, offset_t offset)
        int error;
 
        if ((lckdat->l_whence == 2) || (whence == 2)) {
-               if ((error = zfs_getattr(ip, &vap, 0, CRED()) != 0))
+               if ((error = zfs_getattr(ip, &vap, 0, CRED())))
                        return (error);
        }
 
index e432bc4142dba5719a161c7e0b4465542fc2d5d8..f6de4929704f8fc46cd79add324835a9cbd932eb 100644 (file)
@@ -1,5 +1,9 @@
 %{?!packager: %define packager Brian Behlendorf <behlendorf1@llnl.gov>}
 
+%if ! 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version}
+%define not_rpm 1
+%endif
+
 %define module  @PACKAGE@
 %define mkconf  scripts/dkms.mkconf
 
@@ -16,10 +20,12 @@ Source0:        %{module}-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildArch:      noarch
 
-Requires:       dkms >= 2.2.0.3-20
+Requires:       dkms >= 2.2.0.3
 Requires:       spl-dkms = %{version}
 Requires:       gcc, make, perl
+%if 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version}
 Requires:       kernel-devel
+%endif
 Provides:       %{module}-kmod = %{version}
 
 %description
@@ -69,7 +75,7 @@ DKMS_META_ALIAS=`cat $CONFIG_H 2>/dev/null |
 if [ "$SPEC_META_ALIAS" = "$DKMS_META_ALIAS" ]; then
     echo -e
     echo -e "Uninstall of %{module} module ($SPEC_META_ALIAS) beginning:"
-    dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade
+    dkms remove -m %{module} -v %{version} --all %{!?not_rpm:--rpm_safe_upgrade}
 fi
 exit 0
 
index 89f1b4513f0ce4ce7e84c88556fd0391aa17ba15..bf887cf570a7472a595b80f595dc42f18c242af0 100644 (file)
@@ -191,7 +191,10 @@ chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/*
 rm -rf $RPM_BUILD_ROOT
 
 %changelog
-* Mon Sep 25 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
+* Wed Oct 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.3-1
+- Released 0.7.3-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.3
+* Fri Sep 22 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
 - Released 0.7.2-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.2
 * Tue Aug 8 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.1-1
index 70831796448915325c40538c94994aabbeb74713..f61cfd289060c40e8ae469ef71db59a38088743e 100644 (file)
@@ -331,7 +331,10 @@ exit 0
 %endif
 
 %changelog
-* Mon Sep 25 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
+* Wed Oct 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.3-1
+- Released 0.7.3-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.3
+* Fri Sep 22 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
 - Released 0.7.2-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.2
 * Tue Aug 8 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.1-1
index e432bc4142dba5719a161c7e0b4465542fc2d5d8..f6de4929704f8fc46cd79add324835a9cbd932eb 100644 (file)
@@ -1,5 +1,9 @@
 %{?!packager: %define packager Brian Behlendorf <behlendorf1@llnl.gov>}
 
+%if ! 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version}
+%define not_rpm 1
+%endif
+
 %define module  @PACKAGE@
 %define mkconf  scripts/dkms.mkconf
 
@@ -16,10 +20,12 @@ Source0:        %{module}-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildArch:      noarch
 
-Requires:       dkms >= 2.2.0.3-20
+Requires:       dkms >= 2.2.0.3
 Requires:       spl-dkms = %{version}
 Requires:       gcc, make, perl
+%if 0%{?rhel}%{?fedora}%{?mageia}%{?suse_version}
 Requires:       kernel-devel
+%endif
 Provides:       %{module}-kmod = %{version}
 
 %description
@@ -69,7 +75,7 @@ DKMS_META_ALIAS=`cat $CONFIG_H 2>/dev/null |
 if [ "$SPEC_META_ALIAS" = "$DKMS_META_ALIAS" ]; then
     echo -e
     echo -e "Uninstall of %{module} module ($SPEC_META_ALIAS) beginning:"
-    dkms remove -m %{module} -v %{version} --all --rpm_safe_upgrade
+    dkms remove -m %{module} -v %{version} --all %{!?not_rpm:--rpm_safe_upgrade}
 fi
 exit 0
 
index 70831796448915325c40538c94994aabbeb74713..f61cfd289060c40e8ae469ef71db59a38088743e 100644 (file)
@@ -331,7 +331,10 @@ exit 0
 %endif
 
 %changelog
-* Mon Sep 25 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
+* Wed Oct 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.3-1
+- Released 0.7.3-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.3
+* Fri Sep 22 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.2-1
 - Released 0.7.2-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.2
 * Tue Aug 8 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.1-1
index 3a6db40cf0faea3507356b44fcd021418cc51bca..854c2048a572ac3e896a21dbf6be14fe9967dbfd 100755 (executable)
@@ -37,7 +37,7 @@ DEFAULTCOREDIR=/var/tmp/zloop
 
 function usage
 {
-       echo -e "\n$0 [-t <timeout>] [-c <dump directory>]" \
+       echo -e "\n$0 [-t <timeout>] [ -s <vdev size> ] [-c <dump directory>]" \
            "[ -- [extra ztest parameters]]\n" \
            "\n" \
            "  This script runs ztest repeatedly with randomized arguments.\n" \
@@ -49,6 +49,7 @@ function usage
            "  Options:\n" \
            "    -t  Total time to loop for, in seconds. If not provided,\n" \
            "        zloop runs forever.\n" \
+           "    -s  Size of vdev devices.\n" \
            "    -f  Specify working directory for ztest vdev files.\n" \
            "    -c  Specify a core dump directory to use.\n" \
            "    -h  Print this help message.\n" \
@@ -151,9 +152,11 @@ function store_core
 coredir=$DEFAULTCOREDIR
 workdir=$DEFAULTWORKDIR
 timeout=0
-while getopts ":ht:c:f:" opt; do
+size="512m"
+while getopts ":ht:s:c:f:" opt; do
        case $opt in
                t ) [[ $OPTARG -gt 0 ]] && timeout=$OPTARG ;;
+               s ) [[ $OPTARG ]] && size=$OPTARG ;;
                c ) [[ $OPTARG ]] && coredir=$OPTARG ;;
                f ) [[ $OPTARG ]] && workdir=$(readlink -f "$OPTARG") ;;
                h ) usage
@@ -214,7 +217,6 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do
        align=$(((RANDOM % 2) * 3 + 9))
        runtime=$((RANDOM % 100))
        passtime=$((RANDOM % (runtime / 3 + 1) + 10))
-       size=128m
 
        zopt="$zopt -m $mirrors"
        zopt="$zopt -r $raidz"
index a12fc2d43f45eeb5db592bbb023479431bb5ad2e..5583a2554168e3d55f4d1de70cb00f8668c29d3a 100644 (file)
@@ -501,7 +501,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
     'send-c_lz4_disabled', 'send-c_recv_lz4_disabled',
     'send-c_mixed_compression', 'send-c_stream_size_estimate', 'send-cD',
     'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
-    'send-c_recv_dedup']
+    'send-c_recv_dedup', 'send_freeobjects']
 
 [tests/functional/scrub_mirror]
 tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
index 66abfd69689a509a9a8dc3bef806e2c2e907e5ca..c88b71f99fa020d59ca1d7fcf99769c5a18dbc45 100644 (file)
@@ -2255,7 +2255,7 @@ function del_user #<logname> <basedir>
        fi
 
        if id $user > /dev/null 2>&1; then
-               log_must userdel $user
+               log_must_retry "currently used" 5 userdel $user
        fi
 
        [[ -d $basedir/$user ]] && rm -fr $basedir/$user
index d537ecc56b38622f6c9df8d0a401d7e0e0a623b9..e534819327bbeb2e3d7d1bb96b099f52a321ec43 100755 (executable)
@@ -50,7 +50,7 @@ function cleanup
         poolexists $TESTPOOL1 && \
                 log_must zpool destroy -f $TESTPOOL1
 
-        for file in `ls $TESTDIR/file.*`; do
+        for file in `ls $TEST_BASE_DIR/file.*`; do
                log_must rm -f $file
         done
 }
@@ -62,12 +62,12 @@ log_onexit cleanup
 #make raw files to create various configuration pools
 typeset -i i=0
 while (( i < 3 )); do
-       log_must mkfile $FILESIZE $TESTDIR/file.$i
+       log_must truncate -s $FILESIZE $TEST_BASE_DIR/file.$i
 
        (( i = i + 1 ))
 done
 
-fbase=$TESTDIR/file
+fbase=$TEST_BASE_DIR/file
 set -A poolconf "mirror $fbase.0 $fbase.1 $fbase.2" \
                 "raidz1 $fbase.0 $fbase.1 $fbase.2" \
                 "raidz2 $fbase.0 $fbase.1 $fbase.2"
index 51986e6c29a3af369bf69df11dd3ed7c3622280f..d4d229cc9382aaacf69ebec84b48323b2b5e251b 100644 (file)
@@ -50,9 +50,9 @@ function create_old_pool
        for pool_file in $pool_files; do
                log_must bzcat \
                    $STF_SUITE/tests/functional/cli_root/zpool_upgrade/$pool_file.bz2 \
-                   >/$TESTPOOL/$pool_file
+                   >$TEST_BASE_DIR/$pool_file
        done
-       log_must zpool import -d /$TESTPOOL $pool_name
+       log_must zpool import -d $TEST_BASE_DIR $pool_name
 
        # Put some random contents into the pool
        for i in {1..1024} ; do
@@ -97,7 +97,7 @@ function destroy_upgraded_pool
                log_must zpool destroy $pool_name
        fi
        for file in $pool_files; do
-               rm -f /$TESTPOOL/$file
+               rm -f $TEST_BASE_DIR/$file
        done
 }
 
@@ -112,8 +112,8 @@ function check_pool
        typeset pool=$1
        typeset flag=$2
        find /$pool -type f -exec cksum {} + > \
-               /$TESTPOOL/pool-checksums.$pool.$flag
-       echo /$TESTPOOL/pool-checksums.$pool.$flag
+               $TEST_BASE_DIR/pool-checksums.$pool.$flag
+       echo $TEST_BASE_DIR/pool-checksums.$pool.$flag
 }
 
 # This function simply checks that a pool has a particular version number
index 97325e9b1f9db75ea753f25f55d725430529b3f6..241cd2d8070d7fcec89e42a8a418eabea0114b13 100755 (executable)
@@ -78,10 +78,10 @@ for config in $CONFIGS ; do
        typeset -n pool_name=ZPOOL_VERSION_${config}_NAME
 
        check_pool $pool_name post > /dev/null
-       log_must diff /$TESTPOOL/pool-checksums.$pool_name.pre \
-           /$TESTPOOL/pool-checksums.$pool_name.post
-       rm /$TESTPOOL/pool-checksums.$pool_name.pre \
-           /$TESTPOOL/pool-checksums.$pool_name.post
+       log_must diff $TEST_BASE_DIR/pool-checksums.$pool_name.pre \
+           $TEST_BASE_DIR/pool-checksums.$pool_name.post
+       rm $TEST_BASE_DIR/pool-checksums.$pool_name.pre \
+           $TEST_BASE_DIR/pool-checksums.$pool_name.post
        destroy_upgraded_pool $config
 done
 
index 7258e635bca653166eb6bf64c9ddb308c89d63de..a6ef964ac5fc9ecab7621e1f584ac01ba3231b86 100755 (executable)
@@ -56,12 +56,9 @@ log_assert "async_destroy can suspend and resume traversal"
 
 log_must zfs create -o recordsize=512 -o compression=off $TEST_FS
 
-# Create enough blocks that it will take 4 TXGs to free them all.
-typeset zfs_free_max_blocks=100000
-typeset blocks=$((zfs_free_max_blocks * 4 * 512 / 1024 / 1024))
-
-log_must dd bs=1024k count=$blocks if=/dev/zero of=/$TEST_FS/file
-
+# Create enough blocks that it will take multiple TXGs to free them all.
+log_must dd bs=1024k count=128 if=/dev/zero of=/$TEST_FS/file
+log_must sync
 log_must zfs destroy $TEST_FS
 
 #
index b9f8dba658334e26d6ad7382c0dbb91df6cda010..60ca776ba07e0ca1c8e8cf3f1ba493fa2c95bbc9 100644 (file)
@@ -37,4 +37,5 @@ dist_pkgdata_SCRIPTS = \
        send-c_verify_ratio.ksh \
        send-c_volume.ksh \
        send-c_zstreamdump.ksh \
-       send-cpL_varied_recsize.ksh
+       send-cpL_varied_recsize.ksh \
+       send_freeobjects.ksh
index 760071398141590420f4c9063199a42f1bbf6769..ba5d43f814122307d7dbb4ebf930843fe227d233 100644 (file)
@@ -425,7 +425,8 @@ dist_pkgdata_SCRIPTS = \
        send-c_verify_ratio.ksh \
        send-c_volume.ksh \
        send-c_zstreamdump.ksh \
-       send-cpL_varied_recsize.ksh
+       send-cpL_varied_recsize.ksh \
+       send_freeobjects.ksh
 
 all: all-am
 
index fde4123be872e60bde573f58942db36b2c4ce9c7..294d79807571c083db7897630dce9a3401574cdc 100644 (file)
@@ -513,11 +513,13 @@ function test_fs_setup
 {
        typeset sendfs=$1
        typeset recvfs=$2
+       typeset streamfs=$3
        typeset sendpool=${sendfs%%/*}
        typeset recvpool=${recvfs%%/*}
 
        datasetexists $sendfs && log_must zfs destroy -r $sendpool
        datasetexists $recvfs && log_must zfs destroy -r $recvpool
+       datasetexists $streamfs && log_must zfs destroy -r $streamfs
 
        if $(datasetexists $sendfs || zfs create -o compress=lz4 $sendfs); then
                mk_files 1000 256 0 $sendfs &
@@ -546,10 +548,7 @@ function test_fs_setup
                    ">/$sendpool/incremental.zsend"
        fi
 
-       if datasetexists $streamfs; then
-               log_must zfs destroy -r $streamfs
-       fi
-       log_must zfs create -o compress=lz4 $sendpool/stream
+       log_must zfs create -o compress=lz4 $streamfs
 }
 
 #
@@ -663,9 +662,10 @@ function resume_cleanup
 {
        typeset sendfs=$1
        typeset streamfs=$2
+       typeset sendpool=${sendfs%%/*}
 
        datasetexists $sendfs && log_must zfs destroy -r $sendfs
        datasetexists $streamfs && log_must zfs destroy -r $streamfs
        cleanup_pool $POOL2
-       rm -f /$POOL/initial.zsend /$POOL/incremental.zsend
+       rm -f /$sendpool/initial.zsend /$sendpool/incremental.zsend
 }
index 771d7e2f04a03160c4842b4534d1affb76ceffcb..9c95587a2ba43806e1d896c1c72f654783ffd09e 100755 (executable)
@@ -48,8 +48,8 @@ sendfs=$POOL/sendfs
 recvfs=$POOL3/recvfs
 streamfs=$POOL2/stream
 
-for sendfs in $POOL2/sendfs $POOL2; do
-       test_fs_setup $sendfs $recvfs
+for sendfs in $POOL2/sendfs $POOL3; do
+       test_fs_setup $sendfs $recvfs $streamfs
        resume_test "zfs send -v $sendfs@a" $streamfs $recvfs
        resume_test "zfs send -v -i @a $sendfs@b" $streamfs $recvfs
        file_check $sendfs $recvfs
index 29bdc4f840ddb2d6c7ed34e7ceebdf27d0c5ac93..b7ecf90916ba8e6b94390faa5b646a37870defd5 100755 (executable)
@@ -42,7 +42,7 @@ streamfs=$POOL/stream
 
 log_onexit resume_cleanup $sendfs $streamfs
 
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
 resume_test "zfs send -D -v $sendfs@a" $streamfs $recvfs
 file_check $sendfs $recvfs
 
index d74844890a9242b3c322b8472642fd0cba82be44..50f2b8890a5cc5c6b400aa56079700bb862bea1f 100755 (executable)
@@ -44,7 +44,7 @@ streamfs=$POOL/stream
 
 log_onexit resume_cleanup $sendfs $streamfs
 
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
 resume_test "zfs send -v -e $sendfs@a" $streamfs $recvfs
 resume_test "zfs send -v -e -i @a $sendfs@b" $streamfs $recvfs
 file_check $sendfs $recvfs
index 487a01426b07cf00dc1cf40fcf63d08d676c376e..dda6602632ba8886514b7aef252c15ff7305cc8a 100755 (executable)
@@ -52,7 +52,7 @@ streamfs=$POOL/stream
 
 log_onexit resume_cleanup $sendfs $streamfs
 
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
 log_must zfs bookmark $sendfs@a $sendfs#bm_a
 log_must zfs destroy $sendfs@a
 log_must zfs receive -v $recvfs </$POOL/initial.zsend
index e7453a0e1ed2c12351b58365cd031bd81e6ea1ad..406a466b3998be9054b1f7d3eb89120b0800b1a2 100755 (executable)
@@ -49,7 +49,7 @@ streamfs=$POOL/stream
 
 log_onexit resume_cleanup $sendfs $streamfs
 
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
 log_must zfs unmount $sendfs
 resume_test "zfs send $sendfs" $streamfs $recvfs
 file_check $sendfs $recvfs
index 9f43b79297b5c0cab64304c38b61b9100db5ba8a..d8d7c40e49313d39eb3df8ad770a32148359c53d 100755 (executable)
@@ -41,7 +41,7 @@ streamfs=$POOL/stream
 log_assert "Verify compressed send streams can be resumed if interrupted"
 log_onexit resume_cleanup $sendfs $streamfs
 
-test_fs_setup $sendfs $recvfs
+test_fs_setup $sendfs $recvfs $streamfs
 resume_test "zfs send -c -v $sendfs@a" $streamfs $recvfs
 resume_test "zfs send -c -v -i @a $sendfs@b" $streamfs $recvfs
 file_check $sendfs $recvfs
diff --git a/tests/zfs-tests/tests/functional/rsend/send_freeobjects.ksh b/tests/zfs-tests/tests/functional/rsend/send_freeobjects.ksh
new file mode 100755 (executable)
index 0000000..6533352
--- /dev/null
@@ -0,0 +1,81 @@
+#!/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify FREEOBJECTS record frees sequential objects (See
+# https://github.com/zfsonlinux/zfs/issues/6694)
+#
+# Strategy:
+# 1. Create three files with sequential object numbers, f1 f2 and f3
+# 2. Delete f2
+# 3. Take snapshot A
+# 4. Delete f3
+# 5. Take snapshot B
+# 6. Receive a full send of A
+# 7. Receive an incremental send of B
+# 8. Fail test if f3 exists on received snapshot B
+#
+
+verify_runnable "both"
+
+log_assert "Verify FREEOBJECTS record frees sequential objects"
+
+sendds=sendfo
+recvds=recvfo
+f1=/$POOL/$sendds/f1
+f2=/$POOL/$sendds/f2
+f3=/$POOL/$sendds/f3
+
+#
+# We need to set xattr=sa and dnodesize=legacy to guarantee sequential
+# object numbers for this test. Otherwise, if we used directory-based
+# xattrs, SELinux extended attributes might consume intervening object
+# numbers.
+#
+log_must zfs create -o xattr=sa -o dnodesize=legacy $POOL/$sendds
+
+tries=100
+for ((i=0; i<$tries; i++)); do
+       touch $f1 $f2 $f3
+       o1=$(ls -li $f1 | awk '{print $1}')
+       o2=$(ls -li $f2 | awk '{print $1}')
+       o3=$(ls -li $f3 | awk '{print $1}')
+
+       if [[ $o2 -ne $(( $o1 + 1 )) ]] || [[ $o3 -ne $(( $o2 + 1 )) ]]; then
+               rm -f $f1 $f2 $f3
+       else
+               break
+       fi
+done
+
+if [[ $i -eq $tries ]]; then
+       log_fail "Failed to create three sequential objects"
+fi
+
+log_must rm $f2
+log_must zfs snap $POOL/$sendds@A
+log_must rm $f3
+log_must zfs snap $POOL/$sendds@B
+log_must eval "zfs send $POOL/$sendds@A | zfs recv $POOL/$recvds"
+log_must eval "zfs send -i $POOL/$sendds@A $POOL/$sendds@B |" \
+       "zfs recv $POOL/$recvds"
+log_mustnot zdb $POOL/$recvds@B $o3
+log_pass "Verify FREEOBJECTS record frees sequential objects"