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>
        
*** 18,28 ****
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright (c) 2011 by Delphix. All rights reserved.
   */
  
  #include <sys/dsl_pool.h>
  #include <sys/dsl_dataset.h>
  #include <sys/dsl_prop.h>
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright (c) 2012 by Delphix. All rights reserved.
   */
  
  #include <sys/dsl_pool.h>
  #include <sys/dsl_dataset.h>
  #include <sys/dsl_prop.h>
*** 38,47 ****
--- 38,49 ----
  #include <sys/zfs_context.h>
  #include <sys/fs/zfs.h>
  #include <sys/zfs_znode.h>
  #include <sys/spa_impl.h>
  #include <sys/dsl_deadlist.h>
+ #include <sys/bptree.h>
+ #include <sys/zfeature.h>
  
  int zfs_no_write_throttle = 0;
  int zfs_write_limit_shift = 3;                  /* 1/8th of physical memory */
  int zfs_txg_synctime_ms = 1000;         /* target millisecs to sync a txg */
  
*** 98,121 ****
  
          return (dp);
  }
  
  int
! dsl_pool_open(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
  {
          int err;
          dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
          dsl_dir_t *dd;
          dsl_dataset_t *ds;
          uint64_t obj;
  
!         rw_enter(&dp->dp_config_rwlock, RW_WRITER);
!         err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
!             &dp->dp_meta_objset);
!         if (err)
!                 goto out;
  
          err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
              DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
              &dp->dp_root_dir_obj);
          if (err)
                  goto out;
--- 100,135 ----
  
          return (dp);
  }
  
  int
! dsl_pool_init(spa_t *spa, uint64_t txg, dsl_pool_t **dpp)
  {
          int err;
          dsl_pool_t *dp = dsl_pool_open_impl(spa, txg);
+ 
+         err = dmu_objset_open_impl(spa, NULL, &dp->dp_meta_rootbp,
+             &dp->dp_meta_objset);
+         if (err != 0)
+                 dsl_pool_close(dp);
+         else
+                 *dpp = dp;
+ 
+         return (err);
+ }
+ 
+ int
+ dsl_pool_open(dsl_pool_t *dp)
+ {
+         int err;
          dsl_dir_t *dd;
          dsl_dataset_t *ds;
          uint64_t obj;
  
!         ASSERT(!dmu_objset_is_dirty_anywhere(dp->dp_meta_objset));
  
+         rw_enter(&dp->dp_config_rwlock, RW_WRITER);
          err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
              DMU_POOL_ROOT_DATASET, sizeof (uint64_t), 1,
              &dp->dp_root_dir_obj);
          if (err)
                  goto out;
*** 127,137 ****
  
          err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir);
          if (err)
                  goto out;
  
!         if (spa_version(spa) >= SPA_VERSION_ORIGIN) {
                  err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd);
                  if (err)
                          goto out;
                  err = dsl_dataset_hold_obj(dp, dd->dd_phys->dd_head_dataset_obj,
                      FTAG, &ds);
--- 141,151 ----
  
          err = dsl_pool_open_special_dir(dp, MOS_DIR_NAME, &dp->dp_mos_dir);
          if (err)
                  goto out;
  
!         if (spa_version(dp->dp_spa) >= SPA_VERSION_ORIGIN) {
                  err = dsl_pool_open_special_dir(dp, ORIGIN_DIR_NAME, &dd);
                  if (err)
                          goto out;
                  err = dsl_dataset_hold_obj(dp, dd->dd_phys->dd_head_dataset_obj,
                      FTAG, &ds);
*** 144,154 ****
                  dsl_dir_close(dd, dp);
                  if (err)
                          goto out;
          }
  
!         if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
                  err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
                      &dp->dp_free_dir);
                  if (err)
                          goto out;
  
--- 158,168 ----
                  dsl_dir_close(dd, dp);
                  if (err)
                          goto out;
          }
  
!         if (spa_version(dp->dp_spa) >= SPA_VERSION_DEADLISTS) {
                  err = dsl_pool_open_special_dir(dp, FREE_DIR_NAME,
                      &dp->dp_free_dir);
                  if (err)
                          goto out;
  
*** 158,184 ****
                          goto out;
                  VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj,
                      dp->dp_meta_objset, obj));
          }
  
          err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
              DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
              &dp->dp_tmp_userrefs_obj);
          if (err == ENOENT)
                  err = 0;
          if (err)
                  goto out;
  
!         err = dsl_scan_init(dp, txg);
  
  out:
          rw_exit(&dp->dp_config_rwlock);
-         if (err)
-                 dsl_pool_close(dp);
-         else
-                 *dpp = dp;
- 
          return (err);
  }
  
  void
  dsl_pool_close(dsl_pool_t *dp)
--- 172,202 ----
                          goto out;
                  VERIFY3U(0, ==, bpobj_open(&dp->dp_free_bpobj,
                      dp->dp_meta_objset, obj));
          }
  
+         if (spa_feature_is_active(dp->dp_spa,
+             &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
                  err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
+                     DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1,
+                     &dp->dp_bptree_obj);
+                 if (err != 0)
+                         goto out;
+         }
+ 
+         err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
              DMU_POOL_TMP_USERREFS, sizeof (uint64_t), 1,
              &dp->dp_tmp_userrefs_obj);
          if (err == ENOENT)
                  err = 0;
          if (err)
                  goto out;
  
!         err = dsl_scan_init(dp, dp->dp_tx.tx_open_txg);
  
  out:
          rw_exit(&dp->dp_config_rwlock);
          return (err);
  }
  
  void
  dsl_pool_close(dsl_pool_t *dp)
*** 468,478 ****
   */
  int
  dsl_pool_sync_context(dsl_pool_t *dp)
  {
          return (curthread == dp->dp_tx.tx_sync_thread ||
!             spa_get_dsl(dp->dp_spa) == NULL);
  }
  
  uint64_t
  dsl_pool_adjustedsize(dsl_pool_t *dp, boolean_t netfree)
  {
--- 486,496 ----
   */
  int
  dsl_pool_sync_context(dsl_pool_t *dp)
  {
          return (curthread == dp->dp_tx.tx_sync_thread ||
!             spa_is_initializing(dp->dp_spa));
  }
  
  uint64_t
  dsl_pool_adjustedsize(dsl_pool_t *dp, boolean_t netfree)
  {
*** 786,800 ****
          objset_t *mos = dp->dp_meta_objset;
  
          ASSERT(dp->dp_tmp_userrefs_obj == 0);
          ASSERT(dmu_tx_is_syncing(tx));
  
!         dp->dp_tmp_userrefs_obj = zap_create(mos, DMU_OT_USERREFS,
!             DMU_OT_NONE, 0, tx);
! 
!         VERIFY(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS,
!             sizeof (uint64_t), 1, &dp->dp_tmp_userrefs_obj, tx) == 0);
  }
  
  static int
  dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj,
      const char *tag, uint64_t *now, dmu_tx_t *tx, boolean_t holding)
--- 804,815 ----
          objset_t *mos = dp->dp_meta_objset;
  
          ASSERT(dp->dp_tmp_userrefs_obj == 0);
          ASSERT(dmu_tx_is_syncing(tx));
  
!         dp->dp_tmp_userrefs_obj = zap_create_link(mos, DMU_OT_USERREFS,
!             DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_TMP_USERREFS, tx);
  }
  
  static int
  dsl_pool_user_hold_rele_impl(dsl_pool_t *dp, uint64_t dsobj,
      const char *tag, uint64_t *now, dmu_tx_t *tx, boolean_t holding)