Print this page
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>


   3  *
   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  */
  24 
  25 #include <sys/dmu.h>
  26 #include <sys/dmu_tx.h>
  27 #include <sys/dsl_pool.h>
  28 #include <sys/dsl_dir.h>
  29 #include <sys/dsl_synctask.h>
  30 #include <sys/metaslab.h>
  31 
  32 #define DST_AVG_BLKSHIFT 14
  33 
  34 /* ARGSUSED */
  35 static int
  36 dsl_null_checkfunc(void *arg1, void *arg2, dmu_tx_t *tx)
  37 {
  38         return (0);
  39 }
  40 
  41 dsl_sync_task_group_t *
  42 dsl_sync_task_group_create(dsl_pool_t *dp)


  68         list_insert_tail(&dstg->dstg_tasks, dst);
  69 
  70         dstg->dstg_space += blocks_modified << DST_AVG_BLKSHIFT;
  71 }
  72 
  73 int
  74 dsl_sync_task_group_wait(dsl_sync_task_group_t *dstg)
  75 {
  76         dmu_tx_t *tx;
  77         uint64_t txg;
  78         dsl_sync_task_t *dst;
  79 
  80 top:
  81         tx = dmu_tx_create_dd(dstg->dstg_pool->dp_mos_dir);
  82         VERIFY(0 == dmu_tx_assign(tx, TXG_WAIT));
  83 
  84         txg = dmu_tx_get_txg(tx);
  85 
  86         /* Do a preliminary error check. */
  87         dstg->dstg_err = 0;
  88         rw_enter(&dstg->dstg_pool->dp_config_rwlock, RW_READER);
  89         for (dst = list_head(&dstg->dstg_tasks); dst;
  90             dst = list_next(&dstg->dstg_tasks, dst)) {
  91 #ifdef ZFS_DEBUG
  92                 /*
  93                  * Only check half the time, otherwise, the sync-context
  94                  * check will almost never fail.
  95                  */
  96                 if (spa_get_random(2) == 0)
  97                         continue;
  98 #endif



  99                 dst->dst_err =
 100                     dst->dst_checkfunc(dst->dst_arg1, dst->dst_arg2, tx);
 101                 if (dst->dst_err)
 102                         dstg->dstg_err = dst->dst_err;
 103         }
 104         rw_exit(&dstg->dstg_pool->dp_config_rwlock);
 105 
 106         if (dstg->dstg_err) {
 107                 dmu_tx_commit(tx);
 108                 return (dstg->dstg_err);
 109         }

 110 
 111         /*
 112          * We don't generally have many sync tasks, so pay the price of
 113          * add_tail to get the tasks executed in the right order.
 114          */
 115         VERIFY(0 == txg_list_add_tail(&dstg->dstg_pool->dp_sync_tasks,
 116             dstg, txg));
 117 
 118         dmu_tx_commit(tx);
 119 
 120         txg_wait_synced(dstg->dstg_pool, txg);
 121 
 122         if (dstg->dstg_err == EAGAIN) {
 123                 txg_wait_synced(dstg->dstg_pool, txg + TXG_DEFER_SIZE);
 124                 goto top;
 125         }
 126 
 127         return (dstg->dstg_err);
 128 }
 129 




   3  *
   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) 2012 by Delphix. All rights reserved.
  24  */
  25 
  26 #include <sys/dmu.h>
  27 #include <sys/dmu_tx.h>
  28 #include <sys/dsl_pool.h>
  29 #include <sys/dsl_dir.h>
  30 #include <sys/dsl_synctask.h>
  31 #include <sys/metaslab.h>
  32 
  33 #define DST_AVG_BLKSHIFT 14
  34 
  35 /* ARGSUSED */
  36 static int
  37 dsl_null_checkfunc(void *arg1, void *arg2, dmu_tx_t *tx)
  38 {
  39         return (0);
  40 }
  41 
  42 dsl_sync_task_group_t *
  43 dsl_sync_task_group_create(dsl_pool_t *dp)


  69         list_insert_tail(&dstg->dstg_tasks, dst);
  70 
  71         dstg->dstg_space += blocks_modified << DST_AVG_BLKSHIFT;
  72 }
  73 
  74 int
  75 dsl_sync_task_group_wait(dsl_sync_task_group_t *dstg)
  76 {
  77         dmu_tx_t *tx;
  78         uint64_t txg;
  79         dsl_sync_task_t *dst;
  80 
  81 top:
  82         tx = dmu_tx_create_dd(dstg->dstg_pool->dp_mos_dir);
  83         VERIFY(0 == dmu_tx_assign(tx, TXG_WAIT));
  84 
  85         txg = dmu_tx_get_txg(tx);
  86 
  87         /* Do a preliminary error check. */
  88         dstg->dstg_err = 0;



  89 #ifdef ZFS_DEBUG
  90         /*
  91          * Only check half the time, otherwise, the sync-context
  92          * check will almost never fail.
  93          */
  94         if (spa_get_random(2) == 0)
  95                 goto skip;
  96 #endif
  97         rw_enter(&dstg->dstg_pool->dp_config_rwlock, RW_READER);
  98         for (dst = list_head(&dstg->dstg_tasks); dst;
  99             dst = list_next(&dstg->dstg_tasks, dst)) {
 100                 dst->dst_err =
 101                     dst->dst_checkfunc(dst->dst_arg1, dst->dst_arg2, tx);
 102                 if (dst->dst_err)
 103                         dstg->dstg_err = dst->dst_err;
 104         }
 105         rw_exit(&dstg->dstg_pool->dp_config_rwlock);
 106 
 107         if (dstg->dstg_err) {
 108                 dmu_tx_commit(tx);
 109                 return (dstg->dstg_err);
 110         }
 111 skip:
 112 
 113         /*
 114          * We don't generally have many sync tasks, so pay the price of
 115          * add_tail to get the tasks executed in the right order.
 116          */
 117         VERIFY(0 == txg_list_add_tail(&dstg->dstg_pool->dp_sync_tasks,
 118             dstg, txg));
 119 
 120         dmu_tx_commit(tx);
 121 
 122         txg_wait_synced(dstg->dstg_pool, txg);
 123 
 124         if (dstg->dstg_err == EAGAIN) {
 125                 txg_wait_synced(dstg->dstg_pool, txg + TXG_DEFER_SIZE);
 126                 goto top;
 127         }
 128 
 129         return (dstg->dstg_err);
 130 }
 131