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>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   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  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.

  24  */
  25 
  26 #include <sys/zfs_context.h>
  27 #include <sys/dsl_userhold.h>
  28 #include <sys/dsl_dataset.h>
  29 #include <sys/dsl_synctask.h>
  30 #include <sys/dmu_tx.h>
  31 #include <sys/dsl_pool.h>
  32 #include <sys/dsl_dir.h>
  33 #include <sys/dmu_traverse.h>
  34 #include <sys/dsl_scan.h>
  35 #include <sys/dmu_objset.h>
  36 #include <sys/zap.h>
  37 #include <sys/zfeature.h>
  38 #include <sys/zfs_ioctl.h>
  39 #include <sys/dsl_deleg.h>
  40 
  41 typedef struct dmu_snapshots_destroy_arg {
  42         nvlist_t *dsda_snaps;
  43         nvlist_t *dsda_successful_snaps;


 110                         continue;
 111 
 112                 if (error == 0) {
 113                         error = dsl_destroy_snapshot_check_impl(ds,
 114                             dsda->dsda_defer);
 115                         dsl_dataset_rele(ds, FTAG);
 116                 }
 117 
 118                 if (error == 0) {
 119                         fnvlist_add_boolean(dsda->dsda_successful_snaps,
 120                             nvpair_name(pair));
 121                 } else {
 122                         fnvlist_add_int32(dsda->dsda_errlist,
 123                             nvpair_name(pair), error);
 124                 }
 125         }
 126 
 127         pair = nvlist_next_nvpair(dsda->dsda_errlist, NULL);
 128         if (pair != NULL)
 129                 return (fnvpair_value_int32(pair));




 130         return (0);
 131 }
 132 
 133 struct process_old_arg {
 134         dsl_dataset_t *ds;
 135         dsl_dataset_t *ds_prev;
 136         boolean_t after_branch_point;
 137         zio_t *pio;
 138         uint64_t used, comp, uncomp;
 139 };
 140 
 141 static int
 142 process_old_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
 143 {
 144         struct process_old_arg *poa = arg;
 145         dsl_pool_t *dp = poa->ds->ds_dir->dd_pool;
 146 
 147         if (bp->blk_birth <= poa->ds->ds_phys->ds_prev_snap_txg) {
 148                 dsl_deadlist_insert(&poa->ds->ds_deadlist, bp, tx);
 149                 if (poa->ds_prev && !poa->after_branch_point &&




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   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  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2013 by Delphix. All rights reserved.
  24  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  25  */
  26 
  27 #include <sys/zfs_context.h>
  28 #include <sys/dsl_userhold.h>
  29 #include <sys/dsl_dataset.h>
  30 #include <sys/dsl_synctask.h>
  31 #include <sys/dmu_tx.h>
  32 #include <sys/dsl_pool.h>
  33 #include <sys/dsl_dir.h>
  34 #include <sys/dmu_traverse.h>
  35 #include <sys/dsl_scan.h>
  36 #include <sys/dmu_objset.h>
  37 #include <sys/zap.h>
  38 #include <sys/zfeature.h>
  39 #include <sys/zfs_ioctl.h>
  40 #include <sys/dsl_deleg.h>
  41 
  42 typedef struct dmu_snapshots_destroy_arg {
  43         nvlist_t *dsda_snaps;
  44         nvlist_t *dsda_successful_snaps;


 111                         continue;
 112 
 113                 if (error == 0) {
 114                         error = dsl_destroy_snapshot_check_impl(ds,
 115                             dsda->dsda_defer);
 116                         dsl_dataset_rele(ds, FTAG);
 117                 }
 118 
 119                 if (error == 0) {
 120                         fnvlist_add_boolean(dsda->dsda_successful_snaps,
 121                             nvpair_name(pair));
 122                 } else {
 123                         fnvlist_add_int32(dsda->dsda_errlist,
 124                             nvpair_name(pair), error);
 125                 }
 126         }
 127 
 128         pair = nvlist_next_nvpair(dsda->dsda_errlist, NULL);
 129         if (pair != NULL)
 130                 return (fnvpair_value_int32(pair));
 131 
 132         if (nvlist_empty(dsda->dsda_successful_snaps))
 133                 return (SET_ERROR(ENOENT));
 134 
 135         return (0);
 136 }
 137 
 138 struct process_old_arg {
 139         dsl_dataset_t *ds;
 140         dsl_dataset_t *ds_prev;
 141         boolean_t after_branch_point;
 142         zio_t *pio;
 143         uint64_t used, comp, uncomp;
 144 };
 145 
 146 static int
 147 process_old_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
 148 {
 149         struct process_old_arg *poa = arg;
 150         dsl_pool_t *dp = poa->ds->ds_dir->dd_pool;
 151 
 152         if (bp->blk_birth <= poa->ds->ds_phys->ds_prev_snap_txg) {
 153                 dsl_deadlist_insert(&poa->ds->ds_deadlist, bp, tx);
 154                 if (poa->ds_prev && !poa->after_branch_point &&