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/spa_misc.c
          +++ new/usr/src/uts/common/fs/zfs/spa_misc.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   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  #include <sys/zfs_context.h>
  28   28  #include <sys/spa_impl.h>
  29   29  #include <sys/zio.h>
  30   30  #include <sys/zio_checksum.h>
  31   31  #include <sys/zio_compress.h>
  32   32  #include <sys/dmu.h>
  33   33  #include <sys/dmu_tx.h>
↓ open down ↓ 7 lines elided ↑ open up ↑
  41   41  #include <sys/unique.h>
  42   42  #include <sys/dsl_pool.h>
  43   43  #include <sys/dsl_dir.h>
  44   44  #include <sys/dsl_prop.h>
  45   45  #include <sys/dsl_scan.h>
  46   46  #include <sys/fs/zfs.h>
  47   47  #include <sys/metaslab_impl.h>
  48   48  #include <sys/arc.h>
  49   49  #include <sys/ddt.h>
  50   50  #include "zfs_prop.h"
       51 +#include "zfeature_common.h"
  51   52  
  52   53  /*
  53   54   * SPA locking
  54   55   *
  55   56   * There are four basic locks for managing spa_t structures:
  56   57   *
  57   58   * spa_namespace_lock (global mutex)
  58   59   *
  59   60   *      This lock must be acquired to do any of the following:
  60   61   *
↓ open down ↓ 148 lines elided ↑ open up ↑
 209  210   *                              for writing.
 210  211   *
 211  212   *      spa_vdev_exit()         Release the config lock, wait for all I/O
 212  213   *                              to complete, sync the updated configs to the
 213  214   *                              cache, and release the namespace lock.
 214  215   *
 215  216   * vdev state is protected by spa_vdev_state_enter() / spa_vdev_state_exit().
 216  217   * Like spa_vdev_enter/exit, these are convenience wrappers -- the actual
 217  218   * locking is, always, based on spa_namespace_lock and spa_config_lock[].
 218  219   *
 219      - * spa_rename() is also implemented within this file since is requires
      220 + * spa_rename() is also implemented within this file since it requires
 220  221   * manipulation of the namespace.
 221  222   */
 222  223  
 223  224  static avl_tree_t spa_namespace_avl;
 224  225  kmutex_t spa_namespace_lock;
 225  226  static kcondvar_t spa_namespace_cv;
 226  227  static int spa_active_count;
 227  228  int spa_max_replication_override = SPA_DVAS_PER_BP;
 228  229  
 229  230  static kmutex_t spa_spare_lock;
↓ open down ↓ 246 lines elided ↑ open up ↑
 476  477          list_create(&spa->spa_config_list, sizeof (spa_config_dirent_t),
 477  478              offsetof(spa_config_dirent_t, scd_link));
 478  479  
 479  480          dp = kmem_zalloc(sizeof (spa_config_dirent_t), KM_SLEEP);
 480  481          dp->scd_path = altroot ? NULL : spa_strdup(spa_config_path);
 481  482          list_insert_head(&spa->spa_config_list, dp);
 482  483  
 483  484          VERIFY(nvlist_alloc(&spa->spa_load_info, NV_UNIQUE_NAME,
 484  485              KM_SLEEP) == 0);
 485  486  
 486      -        if (config != NULL)
      487 +        if (config != NULL) {
      488 +                nvlist_t *features;
      489 +
      490 +                if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ,
      491 +                    &features) == 0) {
      492 +                        VERIFY(nvlist_dup(features, &spa->spa_label_features,
      493 +                            0) == 0);
      494 +                }
      495 +
 487  496                  VERIFY(nvlist_dup(config, &spa->spa_config, 0) == 0);
      497 +        }
 488  498  
      499 +        if (spa->spa_label_features == NULL) {
      500 +                VERIFY(nvlist_alloc(&spa->spa_label_features, NV_UNIQUE_NAME,
      501 +                    KM_SLEEP) == 0);
      502 +        }
      503 +
 489  504          return (spa);
 490  505  }
 491  506  
 492  507  /*
 493  508   * Removes a spa_t from the namespace, freeing up any memory used.  Requires
 494  509   * spa_namespace_lock.  This is called only after the spa_t has been closed and
 495  510   * deactivated.
 496  511   */
 497  512  void
 498  513  spa_remove(spa_t *spa)
↓ open down ↓ 15 lines elided ↑ open up ↑
 514  529  
 515  530          while ((dp = list_head(&spa->spa_config_list)) != NULL) {
 516  531                  list_remove(&spa->spa_config_list, dp);
 517  532                  if (dp->scd_path != NULL)
 518  533                          spa_strfree(dp->scd_path);
 519  534                  kmem_free(dp, sizeof (spa_config_dirent_t));
 520  535          }
 521  536  
 522  537          list_destroy(&spa->spa_config_list);
 523  538  
      539 +        nvlist_free(spa->spa_label_features);
 524  540          nvlist_free(spa->spa_load_info);
 525  541          spa_config_set(spa, NULL);
 526  542  
 527  543          refcount_destroy(&spa->spa_refcount);
 528  544  
 529  545          spa_config_lock_destroy(spa);
 530  546  
 531  547          for (int t = 0; t < TXG_SIZE; t++)
 532  548                  bplist_destroy(&spa->spa_free_bplist[t]);
 533  549  
↓ open down ↓ 488 lines elided ↑ open up ↑
1022 1038  
1023 1039          return (error);
1024 1040  }
1025 1041  
1026 1042  /*
1027 1043   * ==========================================================================
1028 1044   * Miscellaneous functions
1029 1045   * ==========================================================================
1030 1046   */
1031 1047  
     1048 +void
     1049 +spa_activate_mos_feature(spa_t *spa, const char *feature)
     1050 +{
     1051 +        (void) nvlist_add_boolean(spa->spa_label_features, feature);
     1052 +        vdev_config_dirty(spa->spa_root_vdev);
     1053 +}
     1054 +
     1055 +void
     1056 +spa_deactivate_mos_feature(spa_t *spa, const char *feature)
     1057 +{
     1058 +        (void) nvlist_remove_all(spa->spa_label_features, feature);
     1059 +        vdev_config_dirty(spa->spa_root_vdev);
     1060 +}
     1061 +
1032 1062  /*
1033 1063   * Rename a spa_t.
1034 1064   */
1035 1065  int
1036 1066  spa_rename(const char *name, const char *newname)
1037 1067  {
1038 1068          spa_t *spa;
1039 1069          int err;
1040 1070  
1041 1071          /*
↓ open down ↓ 130 lines elided ↑ open up ↑
1172 1202                  while (guid == 0 || spa_guid_exists(guid, 0))
1173 1203                          guid = spa_get_random(-1ULL);
1174 1204          }
1175 1205  
1176 1206          return (guid);
1177 1207  }
1178 1208  
1179 1209  void
1180 1210  sprintf_blkptr(char *buf, const blkptr_t *bp)
1181 1211  {
1182      -        char *type = NULL;
     1212 +        char type[256];
1183 1213          char *checksum = NULL;
1184 1214          char *compress = NULL;
1185 1215  
1186 1216          if (bp != NULL) {
1187      -                type = dmu_ot[BP_GET_TYPE(bp)].ot_name;
     1217 +                if (BP_GET_TYPE(bp) & DMU_OT_NEWTYPE) {
     1218 +                        dmu_object_byteswap_t bswap =
     1219 +                            DMU_OT_BYTESWAP(BP_GET_TYPE(bp));
     1220 +                        (void) snprintf(type, sizeof (type), "bswap %s %s",
     1221 +                            DMU_OT_IS_METADATA(BP_GET_TYPE(bp)) ?
     1222 +                            "metadata" : "data",
     1223 +                            dmu_ot_byteswap[bswap].ob_name);
     1224 +                } else {
     1225 +                        (void) strlcpy(type, dmu_ot[BP_GET_TYPE(bp)].ot_name,
     1226 +                            sizeof (type));
     1227 +                }
1188 1228                  checksum = zio_checksum_table[BP_GET_CHECKSUM(bp)].ci_name;
1189 1229                  compress = zio_compress_table[BP_GET_COMPRESS(bp)].ci_name;
1190 1230          }
1191 1231  
1192 1232          SPRINTF_BLKPTR(snprintf, ' ', buf, bp, type, checksum, compress);
1193 1233  }
1194 1234  
1195 1235  void
1196 1236  spa_freeze(spa_t *spa)
1197 1237  {
↓ open down ↓ 61 lines elided ↑ open up ↑
1259 1299  {
1260 1300          return (spa->spa_async_suspended);
1261 1301  }
1262 1302  
1263 1303  dsl_pool_t *
1264 1304  spa_get_dsl(spa_t *spa)
1265 1305  {
1266 1306          return (spa->spa_dsl_pool);
1267 1307  }
1268 1308  
     1309 +boolean_t
     1310 +spa_is_initializing(spa_t *spa)
     1311 +{
     1312 +        return (spa->spa_is_initializing);
     1313 +}
     1314 +
1269 1315  blkptr_t *
1270 1316  spa_get_rootblkptr(spa_t *spa)
1271 1317  {
1272 1318          return (&spa->spa_ubsync.ub_rootbp);
1273 1319  }
1274 1320  
1275 1321  void
1276 1322  spa_set_rootblkptr(spa_t *spa, const blkptr_t *bp)
1277 1323  {
1278 1324          spa->spa_uberblock.ub_rootbp = *bp;
↓ open down ↓ 263 lines elided ↑ open up ↑
1542 1588          spa_mode_global = mode;
1543 1589  
1544 1590          refcount_init();
1545 1591          unique_init();
1546 1592          zio_init();
1547 1593          dmu_init();
1548 1594          zil_init();
1549 1595          vdev_cache_stat_init();
1550 1596          zfs_prop_init();
1551 1597          zpool_prop_init();
     1598 +        zpool_feature_init();
1552 1599          spa_config_load();
1553 1600          l2arc_start();
1554 1601  }
1555 1602  
1556 1603  void
1557 1604  spa_fini(void)
1558 1605  {
1559 1606          l2arc_stop();
1560 1607  
1561 1608          spa_evict_all();
↓ open down ↓ 130 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX