Print this page
3740 Poor ZFS send / receive performance due to snapshot hold / release processing
Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  26  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  27  * Copyright (c) 2013 by Delphix. All rights reserved.
  28  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.

  29  */
  30 
  31 /*
  32  * ZFS ioctls.
  33  *
  34  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  35  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  36  *
  37  * There are two ways that we handle ioctls: the legacy way where almost
  38  * all of the logic is in the ioctl callback, and the new way where most
  39  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  40  *
  41  * Non-legacy ioctls should be registered by calling
  42  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  43  * from userland by lzc_ioctl().
  44  *
  45  * The registration arguments are as follows:
  46  *
  47  * const char *name
  48  *   The name of the ioctl.  This is used for history logging.  If the


4963 zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
4964 {
4965         return (dsl_dataset_get_holds(snapname, outnvl));
4966 }
4967 
4968 /*
4969  * innvl: {
4970  *     snapname -> { holdname, ... }
4971  *     ...
4972  * }
4973  *
4974  * outnvl: {
4975  *     snapname -> error value (int32)
4976  *     ...
4977  * }
4978  */
4979 /* ARGSUSED */
4980 static int
4981 zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
4982 {
4983         nvpair_t *pair;
4984 
4985         /*
4986          * The release may cause the snapshot to be destroyed; make sure it
4987          * is not mounted.
4988          */
4989         for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
4990             pair = nvlist_next_nvpair(holds, pair))
4991                 zfs_unmount_snap(nvpair_name(pair));
4992 
4993         return (dsl_dataset_user_release(holds, errlist));
4994 }
4995 
4996 /*
4997  * inputs:
4998  * zc_name              name of new filesystem or snapshot
4999  * zc_value             full name of old snapshot
5000  *
5001  * outputs:
5002  * zc_cookie            space in bytes
5003  * zc_objset_type       compressed space in bytes
5004  * zc_perm_action       uncompressed space in bytes
5005  */
5006 static int
5007 zfs_ioc_space_written(zfs_cmd_t *zc)
5008 {
5009         int error;
5010         dsl_pool_t *dp;
5011         dsl_dataset_t *new, *old;
5012 




   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Portions Copyright 2011 Martin Matuska
  25  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  26  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  27  * Copyright (c) 2013 by Delphix. All rights reserved.
  28  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  29  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  30  */
  31 
  32 /*
  33  * ZFS ioctls.
  34  *
  35  * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
  36  * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
  37  *
  38  * There are two ways that we handle ioctls: the legacy way where almost
  39  * all of the logic is in the ioctl callback, and the new way where most
  40  * of the marshalling is handled in the common entry point, zfsdev_ioctl().
  41  *
  42  * Non-legacy ioctls should be registered by calling
  43  * zfs_ioctl_register() from zfs_ioctl_init().  The ioctl is invoked
  44  * from userland by lzc_ioctl().
  45  *
  46  * The registration arguments are as follows:
  47  *
  48  * const char *name
  49  *   The name of the ioctl.  This is used for history logging.  If the


4964 zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
4965 {
4966         return (dsl_dataset_get_holds(snapname, outnvl));
4967 }
4968 
4969 /*
4970  * innvl: {
4971  *     snapname -> { holdname, ... }
4972  *     ...
4973  * }
4974  *
4975  * outnvl: {
4976  *     snapname -> error value (int32)
4977  *     ...
4978  * }
4979  */
4980 /* ARGSUSED */
4981 static int
4982 zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
4983 {










4984         return (dsl_dataset_user_release(holds, errlist));
4985 }
4986 
4987 /*
4988  * inputs:
4989  * zc_name              name of new filesystem or snapshot
4990  * zc_value             full name of old snapshot
4991  *
4992  * outputs:
4993  * zc_cookie            space in bytes
4994  * zc_objset_type       compressed space in bytes
4995  * zc_perm_action       uncompressed space in bytes
4996  */
4997 static int
4998 zfs_ioc_space_written(zfs_cmd_t *zc)
4999 {
5000         int error;
5001         dsl_pool_t *dp;
5002         dsl_dataset_t *new, *old;
5003