Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dsl_pool.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_pool.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright (c) 2011 by Delphix. All rights reserved.
       23 + * Copyright (c) 2012 by Delphix. All rights reserved.
  24   24   */
  25   25  
  26   26  #include <sys/dsl_pool.h>
  27   27  #include <sys/dsl_dataset.h>
  28   28  #include <sys/dsl_prop.h>
  29   29  #include <sys/dsl_dir.h>
  30   30  #include <sys/dsl_synctask.h>
  31   31  #include <sys/dsl_scan.h>
  32   32  #include <sys/dnode.h>
  33   33  #include <sys/dmu_tx.h>
  34   34  #include <sys/dmu_objset.h>
  35   35  #include <sys/arc.h>
  36   36  #include <sys/zap.h>
  37   37  #include <sys/zio.h>
  38   38  #include <sys/zfs_context.h>
  39   39  #include <sys/fs/zfs.h>
  40   40  #include <sys/zfs_znode.h>
  41   41  #include <sys/spa_impl.h>
  42   42  #include <sys/dsl_deadlist.h>
       43 +#include <sys/bptree.h>
       44 +#include <sys/zfeature.h>
  43   45  
  44   46  int zfs_no_write_throttle = 0;
  45   47  int zfs_write_limit_shift = 3;                  /* 1/8th of physical memory */
  46   48  int zfs_txg_synctime_ms = 1000;         /* target millisecs to sync a txg */
  47   49  
  48   50  uint64_t zfs_write_limit_min = 32 << 20;        /* min write limit is 32MB */
  49   51  uint64_t zfs_write_limit_max = 0;               /* max data payload per txg */
  50   52  uint64_t zfs_write_limit_inflated = 0;
  51   53  uint64_t zfs_write_limit_override = 0;
  52   54  
↓ open down ↓ 40 lines elided ↑ open up ↑
  93   95  
  94   96          mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL);
  95   97  
  96   98          dp->dp_vnrele_taskq = taskq_create("zfs_vn_rele_taskq", 1, minclsyspri,
  97   99              1, 4, 0);
  98  100  
  99  101          return (dp);
 100  102  }
 101  103  
 102  104  int
 103      -dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
      105 +dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
 104  106  {
 105  107          int err;
 106  108          dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
      109 +
      110 +        err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
      111 +            &dp->dp_meta_objset);
      112 +        if (err != 0)
      113 +                dsl_pool_close(dp);
      114 +        else
      115 +                *dpp = dp;
      116 +
      117 +        return (err);
      118 +}
      119 +
      120 +int
      121 +dsl_pool_open(dsl_pool_t *dp)
      122 +{
      123 +        int err;
 107  124          dsl_dir_t *dd;
 108  125          dsl_dataset_t *ds;
 109  126          uint64_t obj;
 110  127  
 111      -        rw_enter(&dp->dp_config_rwlock, RW_WRITER);
 112      -        err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
 113      -            &dp->dp_meta_objset);
 114      -        if (err)
 115      -                goto out;
      128 +        ASSERT(!dmu_objset_is_dirty_anywhere(dp->dp_meta_objset));
 116  129  
      130 +        rw_enter(&dp->dp_config_rwlock, RW_WRITER);
 117  131          err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
 118  132              DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
 119  133              &dp->dp_root_dir_obj);
 120  134          if (err)
 121  135                  goto out;
 122  136  
 123  137          err = dsl_dir_open_obj(dp, dp->dp_root_dir_obj,
 124  138              NULL, dp, &dp->dp_root_dir);
 125  139          if (err)
 126  140                  goto out;
 127  141  
 128  142          err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir);
 129  143          if (err)
 130  144                  goto out;
 131  145  
 132      -        if (spa_version(spa) >= SPA_VERSION_ORIGIN) {
      146 +        if (spa_version(dp->dp_spa) >= SPA_VERSION_ORIGIN) {
 133  147                  err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd);
 134  148                  if (err)
 135  149                          goto out;
 136  150                  err = dsl_dataset_hold_obj(dp, dd->dd_phys->dd_head_dataset_obj,
 137  151                      FTAG, &ds);
 138  152                  if (err == 0) {
 139  153                          err = dsl_dataset_hold_obj(dp,
 140  154                              ds->ds_phys->ds_prev_snap_obj, dp,
 141  155                              &dp->dp_origin_snap);
 142  156                          dsl_dataset_rele(ds, FTAG);
 143  157                  }
 144  158                  dsl_dir_close(dd, dp);
 145  159                  if (err)
 146  160                          goto out;
 147  161          }
 148  162  
 149      -        if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
      163 +        if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
 150  164                  err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
 151  165                      &dp->dp_free_dir);
 152  166                  if (err)
 153  167                          goto out;
 154  168  
 155  169                  err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
 156  170                      DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj);
 157  171                  if (err)
 158  172                          goto out;
 159  173                  VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj,
 160  174                      dp->dp_meta_objset, obj));
 161  175          }
 162  176  
      177 +        if (spa_feature_is_active(dp->dp_spa,
      178 +            &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
      179 +                err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
      180 +                    DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
      181 +                    &dp->dp_bptree_obj);
      182 +                if (err != 0)
      183 +                        goto out;
      184 +        }
      185 +
 163  186          err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
 164  187              DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
 165  188              &dp->dp_tmp_userrefs_obj);
 166  189          if (err == ENOENT)
 167  190                  err = 0;
 168  191          if (err)
 169  192                  goto out;
 170  193  
 171      -        err = dsl_scan_init(dp, txg);
      194 +        err = dsl_scan_init(dp, dp->dp_tx.tx_open_txg);
 172  195  
 173  196  out:
 174  197          rw_exit(&dp->dp_config_rwlock);
 175      -        if (err)
 176      -                dsl_pool_close(dp);
 177      -        else
 178      -                *dpp = dp;
 179      -
 180  198          return (err);
 181  199  }
 182  200  
 183  201  void
 184  202  dsl_pool_close(dsl_pool_t *dp)
 185  203  {
 186  204          /* drop our references from dsl_pool_open() */
 187  205  
 188  206          /*
 189  207           * Since we held the origin_snap from "syncing" context (which
↓ open down ↓ 273 lines elided ↑ open up ↑
 463  481  }
 464  482  
 465  483  /*
 466  484   * TRUE if the current thread is the tx_sync_thread or if we
 467  485   * are being called from SPA context during pool initialization.
 468  486   */
 469  487  int
 470  488  dsl_pool_sync_context(dsl_pool_t *dp)
 471  489  {
 472  490          return (curthread == dp->dp_tx.tx_sync_thread ||
 473      -            spa_get_dsl(dp->dp_spa) == NULL);
      491 +            spa_is_initializing(dp->dp_spa));
 474  492  }
 475  493  
 476  494  uint64_t
 477  495  dsl_pool_adjustedsize(dsl_pool_t *dp, boolean_t netfree)
 478  496  {
 479  497          uint64_t space, resv;
 480  498  
 481  499          /*
 482  500           * Reserve about 1.6% (1/64), or at least 32MB, for allocation
 483  501           * efficiency.
↓ open down ↓ 297 lines elided ↑ open up ↑
 781  799   * Create the pool-wide zap object for storing temporary snapshot holds.
 782  800   */
 783  801  void
 784  802  dsl_pool_user_hold_create_obj(dsl_pool_t *dp, dmu_tx_t *tx)
 785  803  {
 786  804          objset_t *mos = dp->dp_meta_objset;
 787  805  
 788  806          ASSERT(dp->dp_tmp_userrefs_obj == 0);
 789  807          ASSERT(dmu_tx_is_syncing(tx));
 790  808  
 791      -        dp->dp_tmp_userrefs_obj = zap_create(mos, DMU_OT_USERREFS,
 792      -            DMU_OT_NONE, 0, tx);
 793      -
 794      -        VERIFY(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS,
 795      -            sizeof (uint64_t), 1, &dp->dp_tmp_userrefs_obj, tx) == 0);
      809 +        dp->dp_tmp_userrefs_obj = zap_create_link(mos, DMU_OT_USERREFS,
      810 +            DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS, tx);
 796  811  }
 797  812  
 798  813  static int
 799  814  dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj,
 800  815      const char *tag, uint64_t *now, dmu_tx_t *tx, boolean_t holding)
 801  816  {
 802  817          objset_t *mos = dp->dp_meta_objset;
 803  818          uint64_t zapobj = dp->dp_tmp_userrefs_obj;
 804  819          char *name;
 805  820          int error;
↓ open down ↓ 47 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX