svn commit: r251757 - in stable/8: . cddl/contrib/opensolaris/cmd/zdb cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/cmd/zhack cddl/contrib/opensolaris/cmd/zpool cddl/contrib/opensolaris...

Martin Matuska mm at FreeBSD.org
Fri Jun 14 19:26:34 UTC 2013


Author: mm
Date: Fri Jun 14 19:26:32 2013
New Revision: 251757
URL: http://svnweb.freebsd.org/changeset/base/251757

Log:
  MFC 246619,247187,247265,247348,247398,247540,247585,248265,248267,248571,
      248976,249004,249042,249047,249188,249195,249196,249206,249207,249319,
      249326,249356,249357,249787,249883,249858
  
  Merge libzfs_core, zfs deadman thread and other ZFS bugfixes and improvements.
  
  MFC r246619:
    Correct spelling of "daemon".  No .Dd bump.
    Noticed by:	Nathan Rich <Nathan.Rich dynastysystems com>
  
  MFC r247187:
    Import vendor change to avoid "unitialized variable" warnings.
  
    Illumos ZFS issues:
    3522 zfs module should not allow uninitialized variables
  
  MFC r247265:
    Merge the ZFS I/O deadman thread from vendor (illumos).
    This feature panics the system on hanging ZFS I/O, helps debugging
    and resumes failed service.
  
    The panic behavior can be controlled with the loader-only tunables:
    vfs.zfs.deadman_enabled (enable or disable panic on stalled ZFS I/O)
    vfs.zfs.deadman_synctime (expiration time for stalled ZFS I/O)
  
    By default, ZFS I/O deadman is enabled by default on amd64 and i386
    excluding virtual guest machines.
  
  MFC r247348:
    Be more verbose on ZFS deadman I/O panic
    Patch suggested upstream.
  
  MFC r247398:
    Import metaslab_sync() speedup from vendor (illumos).
  
    Illumos ZFS issues:
    3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
    3564 spa_sync() spends 5-10% of its time in metaslab_sync() (when not
  	condensing)
    3578 transferring the freed map to the defer map should be constant time
    3579 ztest trips assertion in metaslab_weight()
  
  MFC r247540:
    Fix the zfs_ioctl compat layer to support zfs_cmd size change introduced
    in r247265 (ZFS deadman thread). Both new utilities now support the old
    kernel and new kernel properly detects old utilities.
  
    For future backwards compatibility, the vfs.zfs.version.ioctl read-only
    sysctl has been introduced. With this sysctl zfs utilities will be able
    to detect the ioctl interface version of the currently loaded zfs module.
  
  MFC r247585:
    Merge new read-only zfs properties from vendor (illumos)
  
    Illumos ZFS issues:
    3588 provide zfs properties for logical (uncompressed) space used and
         referenced
  
  MFC r248265:
    Update zfs.8 manpage date (missing in r247585)
  
  MFC r248267:
    Import minor ZFS changes from vendor
  
    Illumos ZFS issues:
    3604 zdb should print bpobjs more verbosely (fix zdb hang)
    3606 zpool status -x shouldn't warn about old on-disk format
  
  MFC r248571:
    MFV 238590, 238592:
    In the first zfs ioctl restructuring phase, the libzfs_core library was
    introduced. It is a new thin library that wraps around kernel ioctl's.
    The idea is to provide a forward-compatible way of dealing with new
    features. Arguments are passed in nvlists and not random zfs_cmd fields,
    new-style ioctls are logged to pool history using a new method of
    history logging.
  
    http://blog.delphix.com/matt/2012/01/17/the-future-of-libzfs/
  
    MFV 247580 [1]:
    To address issues of several deadlocks and race conditions the locking
    code around dsl_dataset was rewritten and the interface to synctasks
    was changed.
  
    User-Visible Changes:
    "zfs snapshot" can create more arbitrary snapshots at once (atomically)
    "zfs destroy" destroys multiple snapshots at once
    "zfs recv" has improved performance
  
    Backward Compatibility:
    I have extended the compatibility layer to support full backward
    compatibility by remapping or rewriting the responsible ioctl arguments.
    Old utilities are fully supported by the new kernel module.
  
    Forward Compatibility:
    New utilities work with old kernels with the following restrictions:
      - creating, destroying, holding and releasing of multiple snapshots
        at once is not supported, this includes recursive (-r) commands
  
    Illumos ZFS issues:
      2882 implement libzfs_core
      2900 "zfs snapshot" should be able to create multiple,
           arbitrary snapshots at once
      3464 zfs synctask code needs restructuring
  
  MFC r248976:
    Call dmu_snapshot_list_next() in zvol.c with dsl_pool_config lock held
  
  MFC r249004:
    Do not check against uninitialized rc and comment out vendor code
  
  MFC r249042:
    Fix possible pool hold leak in dmu_send_impl()
  
    Illumos ZFS issues:
      3645 dmu_send_impl: possibilty of pool hold leak
  
  MFC r249047 (avg):
    spa_open_common: fix argument to zvol_create_minors
  
    Prior to r248571 spa_open was always called with a bare pool name,
    but now it is called with a dataset name instead (spa_lookup handles
    that).
    So, when a ZFS root is mounted spa_open is called with a name of a root
    dataset, which can very well be different from the pool name.
    But zvol_create_minors should be called with the pool name, because it
    performs a recursive traversal of all datasets under the name to find
    all those that are volumes.
  
  MFC r249188:
    Import vendor change to reduce diff, no effect on FreeBSD.
  
    Illumos ZFS issues:
      3517 importing pool with autoreplace=on and "hole" vdevs crashes
  	 syseventd
  
  MFC r249195:
    Merge change from vendor to reduce diff only.
    ZFS dtrace probes are not supported on FreeBSD yet.
  
    Illumos ZFS issues:
      3598 want to dtrace when errors are generated in zfs
  
  MFC r249196:
    Provide a fix for kernel panic if receiving recursive deduplicated
    streams. Problem reported to vendor.
  
    Illumos ZFS issues:
      3692 Panic on zfs receive of a recursive deduplicated stream
  
  MFC r249206:
    Merge vendor change - modify time processing in deadman thread.
  
    Illumos ZFS issues:
      3618 ::zio dcmd does not show timestamp data
  
  MFC r249207:
    Allow zdb to output a histogram of compressed block sizes.
  
    Illumos ZFS issues:
      3641 want a histogram of compressed block sizes
  
  MFC r249319:
    ZFS expects a copyout of zfs_cmd_t on an ioctl error. Our sys_ioctl()
    doesn't copyout in this case.
  
    To solve this a new struct zfs_iocparm_t is introduced consisting of:
    - zfs_ioctl_version (future backwards compatibility purposes)
    - user space pointer to zfs_cmd_t (copyin and copyout)
    - size of zfs_cmd_t (verification purposes)
  
    The copyin and copyout of zfs_cmd_t is now done the illumos (vendor) way
    what makes porting of new changes easier and ensures correct behavior if
    returning an error.
  
  MFC r249326:
    Cast (void *)(uintptr_t) on copyout and copyin of zfs_iocparm_t.zfs_cmd
  
  MFC r249356:
    Merge bugfixes accepted and integrated by vendor. Underlying problems
    have been reported by us and fixed in r240942 and r249196.
  
    Illumos ZFS issues:
      3645 dmu_send_impl: possibilty of pool hold leak
      3692 Panic on zfs receive of a recursive deduplicated stream
  
  MFC r249357:
    Fix libzfs to report error instead of returning zero if trying to hold or
    release a non-existing snapshot of a existing dataset. In recursive case
    error is reported if no snapshots with the requested name have been found.
  
    Illumos ZFS issues:
      3699 zfs hold or release of a non-existent snapshot does not output
  	 error
  
  MFC r249787:
    The zfs synctask code restructuring introduced a new bug that makes it
    impossible to set quota and reservation on pools lower than version 22.
    Problem has been reported and a solution discussed with vendor.
  
    Illumos ZFS issues:
      3739 cannot set zfs quota or reservation on pool version < 22
  
  MFC r249883:
    Respect the enoent_ok flag if reporting error for holding an non-existing
    snapshot.
  
    Related illumos ZFS issue:
      3699 zfs hold or release of a non-existent snapshot does not output error
  
  MFC r249858:
    Merge vendor bugfix for a possible deadlock related to async destroy
    and improve write performance by introducing a new lock protecting
    tx_open_txg.
  
    Illumos ZFS issues:
      3642 dsl_scan_active() should not issue I/O to determine if async
           destroying is active
      3643 txg_delay should not hold the tc_lock

Added:
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
     - copied, changed from r248571, head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
     - copied unchanged from r248571, head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h
  stable/8/cddl/contrib/opensolaris/lib/libzfs_core/
     - copied from r248571, head/cddl/contrib/opensolaris/lib/libzfs_core/
  stable/8/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d
     - copied unchanged from r249195, head/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d
  stable/8/cddl/lib/libzfs_core/
     - copied from r248571, head/cddl/lib/libzfs_core/
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
     - copied, changed from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c
     - copied, changed from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h
     - copied unchanged from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h
     - copied unchanged from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_userhold.h
     - copied unchanged from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_userhold.h
Modified:
  stable/8/Makefile.inc1   (contents, props changed)
  stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb.c
  stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs.8
  stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
  stable/8/cddl/contrib/opensolaris/cmd/zhack/zhack.c
  stable/8/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
  stable/8/cddl/contrib/opensolaris/cmd/ztest/ztest.c
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
  stable/8/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
  stable/8/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
  stable/8/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
  stable/8/cddl/lib/Makefile
  stable/8/cddl/lib/libzfs/Makefile
  stable/8/cddl/sbin/zfs/Makefile
  stable/8/cddl/sbin/zpool/Makefile
  stable/8/cddl/usr.bin/zinject/Makefile
  stable/8/cddl/usr.bin/ztest/Makefile
  stable/8/cddl/usr.sbin/zdb/Makefile
  stable/8/cddl/usr.sbin/zhack/Makefile
  stable/8/rescue/rescue/Makefile
  stable/8/share/mk/bsd.libnames.mk
  stable/8/sys/cddl/compat/opensolaris/sys/cred.h
  stable/8/sys/cddl/compat/opensolaris/sys/sdt.h
  stable/8/sys/cddl/compat/opensolaris/sys/time.h
  stable/8/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c
  stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.c
  stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.h
  stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c
  stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h
  stable/8/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
  stable/8/sys/cddl/contrib/opensolaris/common/zfs/zprop_common.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/Makefile.files
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bplist.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_synctask.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lzjb.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_errlog.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_tx.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_deleg.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_scan.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_synctask.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_boot.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/space_map.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg_impl.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_debug.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_leaf.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_byteswap.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_rlock.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
  stable/8/sys/cddl/contrib/opensolaris/uts/common/sys/feature_tests.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
  stable/8/sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h
Directory Properties:
  stable/8/cddl/   (props changed)
  stable/8/cddl/contrib/opensolaris/   (props changed)
  stable/8/cddl/contrib/opensolaris/cmd/zfs/   (props changed)
  stable/8/cddl/contrib/opensolaris/lib/libzfs/   (props changed)
  stable/8/cddl/lib/   (props changed)
  stable/8/cddl/sbin/   (props changed)
  stable/8/cddl/usr.bin/   (props changed)
  stable/8/cddl/usr.sbin/   (props changed)
  stable/8/rescue/rescue/   (props changed)
  stable/8/share/mk/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/cddl/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/8/Makefile.inc1
==============================================================================
--- stable/8/Makefile.inc1	Fri Jun 14 18:56:37 2013	(r251756)
+++ stable/8/Makefile.inc1	Fri Jun 14 19:26:32 2013	(r251757)
@@ -1140,6 +1140,7 @@ _prebuild_libs=	${_kerberos5_lib_libasn1
 		lib/libopie lib/libpam ${_lib_libthr} \
 		lib/libradius lib/libsbuf lib/libtacplus \
 		${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
+		${_cddl_lib_libzfs_core} \
 		lib/libutil ${_lib_libypclnt} lib/libz lib/msun \
 		${_secure_lib_libcrypto} ${_secure_lib_libssh} \
 		${_secure_lib_libssl}
@@ -1155,7 +1156,9 @@ lib/libopie__L lib/libtacplus__L: lib/li
 .if ${MK_CDDL} != "no"
 _cddl_lib_libumem= cddl/lib/libumem
 _cddl_lib_libnvpair= cddl/lib/libnvpair
+_cddl_lib_libzfs_core= cddl/lib/libzfs_core
 _cddl_lib= cddl/lib
+cddl/lib/libzfs_core__L: cddl/lib/libnvpair__L
 .endif
 
 .if ${MK_CRYPT} != "no"

Modified: stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb.c
==============================================================================
--- stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Fri Jun 14 18:56:37 2013	(r251756)
+++ stable/8/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Fri Jun 14 19:26:32 2013	(r251757)
@@ -21,10 +21,11 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  */
 
 #include <stdio.h>
+#include <unistd.h>
 #include <stdio_ext.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -57,6 +58,7 @@
 #include <sys/arc.h>
 #include <sys/ddt.h>
 #include <sys/zfeature.h>
+#include <zfs_comutil.h>
 #undef ZFS_MAXNAMELEN
 #undef verify
 #include <libzfs.h>
@@ -206,6 +208,27 @@ dump_packed_nvlist(objset_t *os, uint64_
 	nvlist_free(nv);
 }
 
+/* ARGSUSED */
+static void
+dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	spa_history_phys_t *shp = data;
+
+	if (shp == NULL)
+		return;
+
+	(void) printf("\t\tpool_create_len = %llu\n",
+	    (u_longlong_t)shp->sh_pool_create_len);
+	(void) printf("\t\tphys_max_off = %llu\n",
+	    (u_longlong_t)shp->sh_phys_max_off);
+	(void) printf("\t\tbof = %llu\n",
+	    (u_longlong_t)shp->sh_bof);
+	(void) printf("\t\teof = %llu\n",
+	    (u_longlong_t)shp->sh_eof);
+	(void) printf("\t\trecords_lost = %llu\n",
+	    (u_longlong_t)shp->sh_records_lost);
+}
+
 static void
 zdb_nicenum(uint64_t num, char *buf)
 {
@@ -215,18 +238,18 @@ zdb_nicenum(uint64_t num, char *buf)
 		nicenum(num, buf);
 }
 
-const char dump_zap_stars[] = "****************************************";
-const int dump_zap_width = sizeof (dump_zap_stars) - 1;
+const char histo_stars[] = "****************************************";
+const int histo_width = sizeof (histo_stars) - 1;
 
 static void
-dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
+dump_histogram(const uint64_t *histo, int size)
 {
 	int i;
-	int minidx = ZAP_HISTOGRAM_SIZE - 1;
+	int minidx = size - 1;
 	int maxidx = 0;
 	uint64_t max = 0;
 
-	for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
+	for (i = 0; i < size; i++) {
 		if (histo[i] > max)
 			max = histo[i];
 		if (histo[i] > 0 && i > maxidx)
@@ -235,12 +258,14 @@ dump_zap_histogram(uint64_t histo[ZAP_HI
 			minidx = i;
 	}
 
-	if (max < dump_zap_width)
-		max = dump_zap_width;
+	if (max < histo_width)
+		max = histo_width;
 
-	for (i = minidx; i <= maxidx; i++)
-		(void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i],
-		    &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]);
+	for (i = minidx; i <= maxidx; i++) {
+		(void) printf("\t\t\t%3u: %6llu %s\n",
+		    i, (u_longlong_t)histo[i],
+		    &histo_stars[(max - histo[i]) * histo_width / max]);
+	}
 }
 
 static void
@@ -291,19 +316,19 @@ dump_zap_stats(objset_t *os, uint64_t ob
 	    (u_longlong_t)zs.zs_salt);
 
 	(void) printf("\t\tLeafs with 2^n pointers:\n");
-	dump_zap_histogram(zs.zs_leafs_with_2n_pointers);
+	dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE);
 
 	(void) printf("\t\tBlocks with n*5 entries:\n");
-	dump_zap_histogram(zs.zs_blocks_with_n5_entries);
+	dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE);
 
 	(void) printf("\t\tBlocks n/10 full:\n");
-	dump_zap_histogram(zs.zs_blocks_n_tenths_full);
+	dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE);
 
 	(void) printf("\t\tEntries with n chunks:\n");
-	dump_zap_histogram(zs.zs_entries_using_n_chunks);
+	dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE);
 
 	(void) printf("\t\tBuckets with n entries:\n");
-	dump_zap_histogram(zs.zs_buckets_with_n_entries);
+	dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE);
 }
 
 /*ARGSUSED*/
@@ -545,7 +570,7 @@ static void
 dump_metaslab_stats(metaslab_t *msp)
 {
 	char maxbuf[32];
-	space_map_t *sm = &msp->ms_map;
+	space_map_t *sm = msp->ms_map;
 	avl_tree_t *t = sm->sm_pp_root;
 	int free_pct = sm->sm_space * 100 / sm->sm_size;
 
@@ -561,7 +586,7 @@ dump_metaslab(metaslab_t *msp)
 {
 	vdev_t *vd = msp->ms_group->mg_vd;
 	spa_t *spa = vd->vdev_spa;
-	space_map_t *sm = &msp->ms_map;
+	space_map_t *sm = msp->ms_map;
 	space_map_obj_t *smo = &msp->ms_smo;
 	char freebuf[32];
 
@@ -857,21 +882,22 @@ dump_history(spa_t *spa)
 	for (int i = 0; i < num; i++) {
 		uint64_t time, txg, ievent;
 		char *cmd, *intstr;
+		boolean_t printed = B_FALSE;
 
 		if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME,
 		    &time) != 0)
-			continue;
+			goto next;
 		if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD,
 		    &cmd) != 0) {
 			if (nvlist_lookup_uint64(events[i],
 			    ZPOOL_HIST_INT_EVENT, &ievent) != 0)
-				continue;
+				goto next;
 			verify(nvlist_lookup_uint64(events[i],
 			    ZPOOL_HIST_TXG, &txg) == 0);
 			verify(nvlist_lookup_string(events[i],
 			    ZPOOL_HIST_INT_STR, &intstr) == 0);
-			if (ievent >= LOG_END)
-				continue;
+			if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS)
+				goto next;
 
 			(void) snprintf(internalstr,
 			    sizeof (internalstr),
@@ -884,6 +910,14 @@ dump_history(spa_t *spa)
 		(void) localtime_r(&tsec, &t);
 		(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
 		(void) printf("%s %s\n", tbuf, cmd);
+		printed = B_TRUE;
+
+next:
+		if (dump_opt['h'] > 1) {
+			if (!printed)
+				(void) printf("unrecognized record:\n");
+			dump_nvlist(events[i], 2);
+		}
 	}
 }
 
@@ -916,7 +950,7 @@ sprintf_blkptr_compact(char *blkbuf, con
 	const dva_t *dva = bp->blk_dva;
 	int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
 
-	if (dump_opt['b'] >= 5) {
+	if (dump_opt['b'] >= 6) {
 		sprintf_blkptr(blkbuf, bp);
 		return;
 	}
@@ -1496,7 +1530,7 @@ static object_viewer_t *object_viewer[DM
 	dump_zap,		/* other ZAP			*/
 	dump_zap,		/* persistent error log		*/
 	dump_uint8,		/* SPA history			*/
-	dump_uint64,		/* SPA history offsets		*/
+	dump_history_offsets,	/* SPA history offsets		*/
 	dump_zap,		/* Pool properties		*/
 	dump_zap,		/* DSL permissions		*/
 	dump_acl,		/* ZFS ACL			*/
@@ -1661,7 +1695,9 @@ dump_dir(objset_t *os)
 	int print_header = 1;
 	int i, error;
 
+	dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
 	dmu_objset_fast_stat(os, &dds);
+	dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
 
 	if (dds.dds_type < DMU_OST_NUMTYPES)
 		type = objset_types[dds.dds_type];
@@ -1953,11 +1989,13 @@ dump_one_dir(const char *dsname, void *a
 /*
  * Block statistics.
  */
+#define	PSIZE_HISTO_SIZE (SPA_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1)
 typedef struct zdb_blkstats {
-	uint64_t	zb_asize;
-	uint64_t	zb_lsize;
-	uint64_t	zb_psize;
-	uint64_t	zb_count;
+	uint64_t zb_asize;
+	uint64_t zb_lsize;
+	uint64_t zb_psize;
+	uint64_t zb_count;
+	uint64_t zb_psize_histogram[PSIZE_HISTO_SIZE];
 } zdb_blkstats_t;
 
 /*
@@ -1981,6 +2019,9 @@ typedef struct zdb_cb {
 	zdb_blkstats_t	zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1];
 	uint64_t	zcb_dedup_asize;
 	uint64_t	zcb_dedup_blocks;
+	uint64_t	zcb_start;
+	uint64_t	zcb_lastprint;
+	uint64_t	zcb_totalasize;
 	uint64_t	zcb_errors[256];
 	int		zcb_readfails;
 	int		zcb_haderrors;
@@ -2007,6 +2048,7 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *
 		zb->zb_lsize += BP_GET_LSIZE(bp);
 		zb->zb_psize += BP_GET_PSIZE(bp);
 		zb->zb_count++;
+		zb->zb_psize_histogram[BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT]++;
 	}
 
 	if (dump_opt['L'])
@@ -2070,7 +2112,6 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog
 		    NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb));
 
 		free(data);
-
 		if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) {
 			zcb->zcb_haderrors = 1;
 			zcb->zcb_errors[ioerr]++;
@@ -2094,7 +2135,7 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog
 
 	zcb->zcb_readfails = 0;
 
-	if (dump_opt['b'] >= 4) {
+	if (dump_opt['b'] >= 5) {
 		sprintf_blkptr(blkbuf, bp);
 		(void) printf("objset %llu object %llu "
 		    "level %lld offset 0x%llx %s\n",
@@ -2105,6 +2146,28 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog
 		    blkbuf);
 	}
 
+	if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) &&
+	    gethrtime() > zcb->zcb_lastprint + NANOSEC) {
+		uint64_t now = gethrtime();
+		char buf[10];
+		uint64_t bytes = zcb->zcb_type[ZB_TOTAL][ZDB_OT_TOTAL].zb_asize;
+		int kb_per_sec =
+		    1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000));
+		int sec_remaining =
+		    (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec;
+
+		zfs_nicenum(bytes, buf, sizeof (buf));
+		(void) fprintf(stderr,
+		    "\r%5s completed (%4dMB/s) "
+		    "estimated time remaining: %uhr %02umin %02usec        ",
+		    buf, kb_per_sec / 1024,
+		    sec_remaining / 60 / 60,
+		    sec_remaining / 60 % 60,
+		    sec_remaining % 60);
+
+		zcb->zcb_lastprint = now;
+	}
+
 	return (0);
 }
 
@@ -2196,11 +2259,11 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
 			for (int m = 0; m < vd->vdev_ms_count; m++) {
 				metaslab_t *msp = vd->vdev_ms[m];
 				mutex_enter(&msp->ms_lock);
-				space_map_unload(&msp->ms_map);
-				VERIFY(space_map_load(&msp->ms_map,
+				space_map_unload(msp->ms_map);
+				VERIFY(space_map_load(msp->ms_map,
 				    &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
 				    spa->spa_meta_objset) == 0);
-				msp->ms_map.sm_ppd = vd;
+				msp->ms_map->sm_ppd = vd;
 				mutex_exit(&msp->ms_lock);
 			}
 		}
@@ -2223,7 +2286,7 @@ zdb_leak_fini(spa_t *spa)
 			for (int m = 0; m < vd->vdev_ms_count; m++) {
 				metaslab_t *msp = vd->vdev_ms[m];
 				mutex_enter(&msp->ms_lock);
-				space_map_unload(&msp->ms_map);
+				space_map_unload(msp->ms_map);
 				mutex_exit(&msp->ms_lock);
 			}
 		}
@@ -2236,7 +2299,7 @@ count_block_cb(void *arg, const blkptr_t
 {
 	zdb_cb_t *zcb = arg;
 
-	if (dump_opt['b'] >= 4) {
+	if (dump_opt['b'] >= 5) {
 		char blkbuf[BP_SPRINTF_LEN];
 		sprintf_blkptr(blkbuf, bp);
 		(void) printf("[%s] %s\n",
@@ -2255,7 +2318,7 @@ dump_block_stats(spa_t *spa)
 	int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
 	int leaks = 0;
 
-	(void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
+	(void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n",
 	    (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
 	    (dump_opt['c'] == 1) ? "metadata " : "",
 	    dump_opt['c'] ? "checksums " : "",
@@ -2291,6 +2354,8 @@ dump_block_stats(spa_t *spa)
 	if (dump_opt['c'] > 1)
 		flags |= TRAVERSE_PREFETCH_DATA;
 
+	zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa));
+	zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
 	zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
 
 	if (zcb.zcb_haderrors) {
@@ -2418,6 +2483,14 @@ dump_block_stats(spa_t *spa)
 				else
 					(void) printf("    L%d %s\n",
 					    level, typename);
+
+				if (dump_opt['b'] >= 4) {
+					(void) printf("psize "
+					    "(in 512-byte sectors): "
+					    "number of blocks\n");
+					dump_histogram(zb->zb_psize_histogram,
+					    PSIZE_HISTO_SIZE);
+				}
 			}
 		}
 	}

Modified: stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Fri Jun 14 18:56:37 2013	(r251756)
+++ stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Fri Jun 14 19:26:32 2013	(r251757)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 10, 2013
+.Dd March 21, 2013
 .Dt ZFS 8
 .Os
 .Sh NAME
@@ -64,6 +64,7 @@
 .Op Fl r
 .Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
 .Ar filesystem at snapname Ns | Ns Ar volume at snapname
+.Ar filesystem at snapname Ns | Ns Ar volume at snapname Ns ...
 .Nm
 .Cm rollback
 .Op Fl rRf
@@ -519,6 +520,39 @@ if the snapshot has been marked for defe
 .Qq Nm Cm destroy -d
 command. Otherwise, the property is
 .Cm off .
+.It Sy logicalreferenced
+The amount of space that is
+.Qq logically
+accessible by this dataset.
+See the
+.Sy referenced
+property.
+The logical space ignores the effect of the
+.Sy compression
+and
+.Sy copies
+properties, giving a quantity closer to the amount of data that applications
+see.
+However, it does include space consumed by metadata.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy lrefer .
+.It Sy logicalused
+The amount of space that is
+.Qq logically
+consumed by this dataset and all its descendents.
+See the
+.Sy used
+property.
+The logical space ignores the effect of the
+.Sy compression
+and
+.Sy copies
+properties, giving a quantity closer to the amount of data that applications
+see.
+.Pp
+This property can also be referred to by its shortened column name,
+.Sy lused .
 .It Sy mounted
 For file systems, indicates whether the file system is currently mounted. This
 property can be either
@@ -1158,7 +1192,7 @@ When the
 .Sy sharenfs
 property is changed for a dataset, the
 .Xr mountd 8
-dameon is reloaded.
+daemon is reloaded.
 .It Sy logbias Ns = Ns Cm latency | throughput
 Provide a hint to
 .Tn ZFS
@@ -1575,7 +1609,11 @@ multiple snapshots.
 Destroy (or mark for deferred deletion) all snapshots with this name in
 descendent file systems.
 .It Fl R
-Recursively destroy all dependents.
+Recursively destroy all clones of these snapshots, including the clones,
+snapshots, and children.
+If this flag is specified, the
+.Op fl d
+flag will have no effect.
 .It Fl n
 Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
 conjunction with the
@@ -1603,17 +1641,18 @@ behavior for mounted file systems in use
 .Op Fl r
 .Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
 .Ar filesystem at snapname Ns | Ns volume at snapname
+.Ar filesystem at snapname Ns | Ns volume at snapname Ns ...
 .Xc
 .Pp
-Creates a snapshot with the given name. All previous modifications by
-successful system calls to the file system are part of the snapshot. See the
+Creates snapshots with the given names. All previous modifications by
+successful system calls to the file system are part of the snapshots.
+Snapshots are taken atomically, so that all snapshots correspond to the same
+moment in time. See the
 .Qq Sx Snapshots
 section for details.
 .Bl -tag -width indent
 .It Fl r
-Recursively create snapshots of all descendent datasets. Snapshots are taken
-atomically, so that all recursive snapshots correspond to the same moment in
-time.
+Recursively create snapshots of all descendent datasets
 .It Fl o Ar property Ns = Ns Ar value
 Sets the specified property; see
 .Qq Nm Cm create

Modified: stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
==============================================================================
--- stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Fri Jun 14 18:56:37 2013	(r251756)
+++ stable/8/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Fri Jun 14 19:26:32 2013	(r251757)
@@ -58,6 +58,7 @@
 #include <time.h>
 
 #include <libzfs.h>
+#include <libzfs_core.h>
 #include <zfs_prop.h>
 #include <zfs_deleg.h>
 #include <libuutil.h>
@@ -74,6 +75,7 @@ libzfs_handle_t *g_zfs;
 
 static FILE *mnttab_file;
 static char history_str[HIS_MAX_RECORD_LEN];
+static boolean_t log_history = B_TRUE;
 
 static int zfs_do_clone(int argc, char **argv);
 static int zfs_do_create(int argc, char **argv);
@@ -276,7 +278,7 @@ get_usage(zfs_help_t idx)
 		return (gettext("\tshare <-a | filesystem>\n"));
 	case HELP_SNAPSHOT:
 		return (gettext("\tsnapshot [-r] [-o property=value] ... "
-		    "<filesystem at snapname|volume at snapname>\n"));
+		    "<filesystem at snapname|volume at snapname> ...\n"));
 	case HELP_UNMOUNT:
 		return (gettext("\tunmount [-f] "
 		    "<-a | filesystem|mountpoint>\n"));
@@ -903,11 +905,12 @@ typedef struct destroy_cbdata {
 	boolean_t	cb_parsable;
 	boolean_t	cb_dryrun;
 	nvlist_t	*cb_nvl;
+	nvlist_t	*cb_batchedsnaps;
 
 	/* first snap in contiguous run */
-	zfs_handle_t	*cb_firstsnap;
+	char		*cb_firstsnap;
 	/* previous snap in contiguous run */
-	zfs_handle_t	*cb_prevsnap;
+	char		*cb_prevsnap;
 	int64_t		cb_snapused;
 	char		*cb_snapspec;
 } destroy_cbdata_t;
@@ -999,9 +1002,27 @@ destroy_callback(zfs_handle_t *zhp, void
 		zfs_close(zhp);
 		return (0);
 	}
+	if (cb->cb_dryrun) {
+		zfs_close(zhp);
+		return (0);
+	}
+
+	/*
+	 * We batch up all contiguous snapshots (even of different
+	 * filesystems) and destroy them with one ioctl.  We can't
+	 * simply do all snap deletions and then all fs deletions,
+	 * because we must delete a clone before its origin.
+	 */
+	if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
+		fnvlist_add_boolean(cb->cb_batchedsnaps, name);
+	} else {
+		int error = zfs_destroy_snaps_nvl(g_zfs,
+		    cb->cb_batchedsnaps, B_FALSE);
+		fnvlist_free(cb->cb_batchedsnaps);
+		cb->cb_batchedsnaps = fnvlist_alloc();
 
-	if (!cb->cb_dryrun) {
-		if (zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
+		if (error != 0 ||
+		    zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
 		    zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
 			zfs_close(zhp);
 			return (-1);
@@ -1021,11 +1042,13 @@ destroy_print_cb(zfs_handle_t *zhp, void
 
 	if (nvlist_exists(cb->cb_nvl, name)) {
 		if (cb->cb_firstsnap == NULL)
-			cb->cb_firstsnap = zfs_handle_dup(zhp);
+			cb->cb_firstsnap = strdup(name);
 		if (cb->cb_prevsnap != NULL)
-			zfs_close(cb->cb_prevsnap);
+			free(cb->cb_prevsnap);
 		/* this snap continues the current range */
-		cb->cb_prevsnap = zfs_handle_dup(zhp);
+		cb->cb_prevsnap = strdup(name);
+		if (cb->cb_firstsnap == NULL || cb->cb_prevsnap == NULL)
+			nomem();
 		if (cb->cb_verbose) {
 			if (cb->cb_parsable) {
 				(void) printf("destroy\t%s\n", name);
@@ -1040,12 +1063,12 @@ destroy_print_cb(zfs_handle_t *zhp, void
 	} else if (cb->cb_firstsnap != NULL) {
 		/* end of this range */
 		uint64_t used = 0;
-		err = zfs_get_snapused_int(cb->cb_firstsnap,
+		err = lzc_snaprange_space(cb->cb_firstsnap,
 		    cb->cb_prevsnap, &used);
 		cb->cb_snapused += used;
-		zfs_close(cb->cb_firstsnap);
+		free(cb->cb_firstsnap);
 		cb->cb_firstsnap = NULL;
-		zfs_close(cb->cb_prevsnap);
+		free(cb->cb_prevsnap);
 		cb->cb_prevsnap = NULL;
 	}
 	zfs_close(zhp);
@@ -1062,13 +1085,13 @@ destroy_print_snapshots(zfs_handle_t *fs
 	if (cb->cb_firstsnap != NULL) {
 		uint64_t used = 0;
 		if (err == 0) {
-			err = zfs_get_snapused_int(cb->cb_firstsnap,
+			err = lzc_snaprange_space(cb->cb_firstsnap,
 			    cb->cb_prevsnap, &used);
 		}
 		cb->cb_snapused += used;
-		zfs_close(cb->cb_firstsnap);
+		free(cb->cb_firstsnap);
 		cb->cb_firstsnap = NULL;
-		zfs_close(cb->cb_prevsnap);
+		free(cb->cb_prevsnap);
 		cb->cb_prevsnap = NULL;
 	}
 	return (err);
@@ -1155,8 +1178,10 @@ static int
 zfs_do_destroy(int argc, char **argv)
 {
 	destroy_cbdata_t cb = { 0 };
+	int rv = 0;
+	int err = 0;
 	int c;
-	zfs_handle_t *zhp;
+	zfs_handle_t *zhp = NULL;
 	char *at;
 	zfs_type_t type = ZFS_TYPE_DATASET;
 
@@ -1210,11 +1235,9 @@ zfs_do_destroy(int argc, char **argv)
 
 	at = strchr(argv[0], '@');
 	if (at != NULL) {
-		int err = 0;
 
 		/* Build the list of snaps to destroy in cb_nvl. */
-		if (nvlist_alloc(&cb.cb_nvl, NV_UNIQUE_NAME, 0) != 0)
-			nomem();
+		cb.cb_nvl = fnvlist_alloc();
 
 		*at = '\0';
 		zhp = zfs_open(g_zfs, argv[0],
@@ -1225,17 +1248,15 @@ zfs_do_destroy(int argc, char **argv)
 		cb.cb_snapspec = at + 1;
 		if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 ||
 		    cb.cb_error) {
-			zfs_close(zhp);
-			nvlist_free(cb.cb_nvl);
-			return (1);
+			rv = 1;
+			goto out;
 		}
 
 		if (nvlist_empty(cb.cb_nvl)) {
 			(void) fprintf(stderr, gettext("could not find any "
 			    "snapshots to destroy; check snapshot names.\n"));
-			zfs_close(zhp);
-			nvlist_free(cb.cb_nvl);
-			return (1);
+			rv = 1;
+			goto out;
 		}
 
 		if (cb.cb_verbose) {
@@ -1254,18 +1275,26 @@ zfs_do_destroy(int argc, char **argv)
 		}
 
 		if (!cb.cb_dryrun) {
-			if (cb.cb_doclones)
+			if (cb.cb_doclones) {
+				cb.cb_batchedsnaps = fnvlist_alloc();
 				err = destroy_clones(&cb);
+				if (err == 0) {
+					err = zfs_destroy_snaps_nvl(g_zfs,
+					    cb.cb_batchedsnaps, B_FALSE);
+				}
+				if (err != 0) {
+					rv = 1;
+					goto out;
+				}
+			}
 			if (err == 0) {
-				err = zfs_destroy_snaps_nvl(zhp, cb.cb_nvl,
+				err = zfs_destroy_snaps_nvl(g_zfs, cb.cb_nvl,
 				    cb.cb_defer_destroy);
 			}
 		}
 
-		zfs_close(zhp);
-		nvlist_free(cb.cb_nvl);
 		if (err != 0)
-			return (1);
+			rv = 1;
 	} else {
 		/* Open the given dataset */
 		if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
@@ -1286,8 +1315,8 @@ zfs_do_destroy(int argc, char **argv)
 			    zfs_get_name(zhp));
 			(void) fprintf(stderr, gettext("use 'zpool destroy %s' "
 			    "to destroy the pool itself\n"), zfs_get_name(zhp));
-			zfs_close(zhp);
-			return (1);
+			rv = 1;
+			goto out;
 		}
 
 		/*
@@ -1297,30 +1326,42 @@ zfs_do_destroy(int argc, char **argv)
 		if (!cb.cb_doclones &&
 		    zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
 		    &cb) != 0) {
-			zfs_close(zhp);
-			return (1);
+			rv = 1;
+			goto out;
 		}
 
 		if (cb.cb_error) {
-			zfs_close(zhp);
-			return (1);
+			rv = 1;
+			goto out;
 		}
 
+		cb.cb_batchedsnaps = fnvlist_alloc();
 		if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
 		    &cb) != 0) {
-			zfs_close(zhp);
-			return (1);
+			rv = 1;
+			goto out;
 		}
 
 		/*
 		 * Do the real thing.  The callback will close the
 		 * handle regardless of whether it succeeds or not.
 		 */
-		if (destroy_callback(zhp, &cb) != 0)
-			return (1);
+		err = destroy_callback(zhp, &cb);
+		zhp = NULL;
+		if (err == 0) {
+			err = zfs_destroy_snaps_nvl(g_zfs,
+			    cb.cb_batchedsnaps, cb.cb_defer_destroy);
+		}
+		if (err != 0)
+			rv = 1;
 	}
 
-	return (0);
+out:
+	fnvlist_free(cb.cb_batchedsnaps);
+	fnvlist_free(cb.cb_nvl);
+	if (zhp != NULL)
+		zfs_close(zhp);
+	return (rv);
 }
 
 static boolean_t
@@ -1921,9 +1962,11 @@ upgrade_set_callback(zfs_handle_t *zhp, 
 			/*
 			 * If they did "zfs upgrade -a", then we could
 			 * be doing ioctls to different pools.  We need
-			 * to log this history once to each pool.
+			 * to log this history once to each pool, and bypass
+			 * the normal history logging that happens in main().
 			 */
-			verify(zpool_stage_history(g_zfs, history_str) == 0);
+			(void) zpool_log_history(g_zfs, history_str);
+			log_history = B_FALSE;
 		}
 		if (zfs_prop_set(zhp, "version", verstr) == 0)
 			cb->cb_numupgraded++;
@@ -3461,6 +3504,32 @@ zfs_do_set(int argc, char **argv)
 	return (ret);
 }
 
+typedef struct snap_cbdata {
+	nvlist_t *sd_nvl;
+	boolean_t sd_recursive;
+	const char *sd_snapname;
+} snap_cbdata_t;
+
+static int
+zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
+{
+	snap_cbdata_t *sd = arg;
+	char *name;
+	int rv = 0;
+	int error;
+
+	error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
+	if (error == -1)
+		nomem();
+	fnvlist_add_boolean(sd->sd_nvl, name);
+	free(name);
+
+	if (sd->sd_recursive)
+		rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+	zfs_close(zhp);
+	return (rv);
+}
+
 /*
  * zfs snapshot [-r] [-o prop=value] ... <fs at snap>
  *
@@ -3470,13 +3539,16 @@ zfs_do_set(int argc, char **argv)
 static int
 zfs_do_snapshot(int argc, char **argv)
 {
-	boolean_t recursive = B_FALSE;
 	int ret = 0;
 	char c;
 	nvlist_t *props;
+	snap_cbdata_t sd = { 0 };
+	boolean_t multiple_snaps = B_FALSE;
 
 	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
 		nomem();
+	if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0)
+		nomem();
 
 	/* check options */
 	while ((c = getopt(argc, argv, "ro:")) != -1) {
@@ -3486,7 +3558,8 @@ zfs_do_snapshot(int argc, char **argv)
 				return (1);
 			break;
 		case 'r':
-			recursive = B_TRUE;
+			sd.sd_recursive = B_TRUE;
+			multiple_snaps = B_TRUE;
 			break;
 		case '?':
 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
@@ -3503,18 +3576,35 @@ zfs_do_snapshot(int argc, char **argv)
 		(void) fprintf(stderr, gettext("missing snapshot argument\n"));
 		goto usage;
 	}
-	if (argc > 1) {
-		(void) fprintf(stderr, gettext("too many arguments\n"));
-		goto usage;
+
+	if (argc > 1)
+		multiple_snaps = B_TRUE;
+	for (; argc > 0; argc--, argv++) {
+		char *atp;
+		zfs_handle_t *zhp;
+
+		atp = strchr(argv[0], '@');
+		if (atp == NULL)
+			goto usage;
+		*atp = '\0';
+		sd.sd_snapname = atp + 1;
+		zhp = zfs_open(g_zfs, argv[0],
+		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
+		if (zhp == NULL)
+			goto usage;
+		if (zfs_snapshot_cb(zhp, &sd) != 0)
+			goto usage;
 	}
 
-	ret = zfs_snapshot(g_zfs, argv[0], recursive, props);
+	ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props);
+	nvlist_free(sd.sd_nvl);
 	nvlist_free(props);
-	if (ret && recursive)
+	if (ret != 0 && multiple_snaps)
 		(void) fprintf(stderr, gettext("no snapshots were created\n"));
 	return (ret != 0);
 
 usage:
+	nvlist_free(sd.sd_nvl);
 	nvlist_free(props);
 	usage(B_FALSE);
 	return (-1);
@@ -5057,28 +5147,12 @@ cleanup2:
 	return (error);
 }
 
-/*
- * zfs allow [-r] [-t] <tag> <snap> ...
- *
- *	-r	Recursively hold
- *	-t	Temporary hold (hidden option)
- *
- * Apply a user-hold with the given tag to the list of snapshots.
- */
 static int
 zfs_do_allow(int argc, char **argv)
 {
 	return (zfs_do_allow_unallow_impl(argc, argv, B_FALSE));
 }
 
-/*
- * zfs unallow [-r] [-t] <tag> <snap> ...
- *
- *	-r	Recursively hold
- *	-t	Temporary hold (hidden option)
- *
- * Apply a user-hold with the given tag to the list of snapshots.
- */
 static int
 zfs_do_unallow(int argc, char **argv)
 {
@@ -5092,7 +5166,6 @@ zfs_do_hold_rele_impl(int argc, char **a
 	int i;
 	const char *tag;
 	boolean_t recursive = B_FALSE;
-	boolean_t temphold = B_FALSE;
 	const char *opts = holding ? "rt" : "r";
 	int c;
 
@@ -5102,9 +5175,6 @@ zfs_do_hold_rele_impl(int argc, char **a
 		case 'r':
 			recursive = B_TRUE;
 			break;
-		case 't':
-			temphold = B_TRUE;
-			break;
 		case '?':
 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
 			    optopt);
@@ -5153,7 +5223,7 @@ zfs_do_hold_rele_impl(int argc, char **a
 		}
 		if (holding) {
 			if (zfs_hold(zhp, delim+1, tag, recursive,
-			    temphold, B_FALSE, -1, 0, 0) != 0)
+			    B_FALSE, -1) != 0)
 				++errors;
 		} else {
 			if (zfs_release(zhp, delim+1, tag, recursive) != 0)
@@ -5169,7 +5239,6 @@ zfs_do_hold_rele_impl(int argc, char **a
  * zfs hold [-r] [-t] <tag> <snap> ...
  *
  *	-r	Recursively hold
- *	-t	Temporary hold (hidden option)
  *
  * Apply a user-hold with the given tag to the list of snapshots.
  */
@@ -6591,8 +6660,7 @@ main(int argc, char **argv)
 		return (1);
 	}
 
-	zpool_set_history_str("zfs", argc, argv, history_str);
-	verify(zpool_stage_history(g_zfs, history_str) == 0);
+	zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
 
 	libzfs_print_on_error(g_zfs, B_TRUE);
 
@@ -6661,6 +6729,9 @@ main(int argc, char **argv)
 
 	(void) fclose(mnttab_file);
 
+	if (ret == 0 && log_history)
+		(void) zpool_log_history(g_zfs, history_str);
+
 	libzfs_fini(g_zfs);
 
 	/*

Modified: stable/8/cddl/contrib/opensolaris/cmd/zhack/zhack.c
==============================================================================
--- stable/8/cddl/contrib/opensolaris/cmd/zhack/zhack.c	Fri Jun 14 18:56:37 2013	(r251756)
+++ stable/8/cddl/contrib/opensolaris/cmd/zhack/zhack.c	Fri Jun 14 19:26:32 2013	(r251757)
@@ -46,6 +46,7 @@
 #include <sys/zio_checksum.h>
 #include <sys/zio_compress.h>
 #include <sys/zfeature.h>
+#include <sys/dmu_tx.h>
 #undef ZFS_MAXNAMELEN
 #undef verify
 #include <libzfs.h>
@@ -273,12 +274,15 @@ zhack_do_feature_stat(int argc, char **a
 }
 
 static void
-feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx)
+feature_enable_sync(void *arg, dmu_tx_t *tx)
 {
-	spa_t *spa = arg1;
-	zfeature_info_t *feature = arg2;
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+	zfeature_info_t *feature = arg;
 
 	spa_feature_enable(spa, feature, tx);
+	spa_history_log_internal(spa, "zhack enable feature", tx,
+	    "name=%s can_readonly=%u",
+	    feature->fi_guid, feature->fi_can_readonly);
 }
 
 static void
@@ -341,8 +345,8 @@ zhack_do_feature_enable(int argc, char *
 	if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
 		fatal("feature already enabled: %s", feature.fi_guid);
 
-	VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL,
-	    feature_enable_sync, spa, &feature, 5));
+	VERIFY0(dsl_sync_task(spa_name(spa), NULL,
+	    feature_enable_sync, &feature, 5));
 
 	spa_close(spa, FTAG);
 
@@ -350,21 +354,25 @@ zhack_do_feature_enable(int argc, char *
 }
 
 static void
-feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx)
+feature_incr_sync(void *arg, dmu_tx_t *tx)
 {
-	spa_t *spa = arg1;
-	zfeature_info_t *feature = arg2;
+	spa_t *spa = dmu_tx_pool(tx)->dp_spa;
+	zfeature_info_t *feature = arg;
 
 	spa_feature_incr(spa, feature, tx);
+	spa_history_log_internal(spa, "zhack feature incr", tx,
+	    "name=%s", feature->fi_guid);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable-8 mailing list