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>

@@ -16,15 +16,14 @@
  * fields enclosed by brackets "[]" replaced with your own identifying
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
- */
-/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  */
 
 /* Portions Copyright 2010 Robert Milkowski */

@@ -73,10 +72,57 @@
 
 typedef struct objset objset_t;
 typedef struct dmu_tx dmu_tx_t;
 typedef struct dsl_dir dsl_dir_t;
 
+typedef enum dmu_object_byteswap {
+        DMU_BSWAP_UINT8,
+        DMU_BSWAP_UINT16,
+        DMU_BSWAP_UINT32,
+        DMU_BSWAP_UINT64,
+        DMU_BSWAP_ZAP,
+        DMU_BSWAP_DNODE,
+        DMU_BSWAP_OBJSET,
+        DMU_BSWAP_ZNODE,
+        DMU_BSWAP_OLDACL,
+        DMU_BSWAP_ACL,
+        /*
+         * Allocating a new byteswap type number makes the on-disk format
+         * incompatible with any other format that uses the same number.
+         *
+         * Data can usually be structured to work with one of the
+         * DMU_BSWAP_UINT* or DMU_BSWAP_ZAP types.
+         */
+        DMU_BSWAP_NUMFUNCS
+} dmu_object_byteswap_t;
+
+#define DMU_OT_NEWTYPE 0x80
+#define DMU_OT_METADATA 0x40
+#define DMU_OT_BYTESWAP_MASK 0x3f
+
+/*
+ * Defines a uint8_t object type. Object types specify if the data
+ * in the object is metadata (boolean) and how to byteswap the data
+ * (dmu_object_byteswap_t).
+ */
+#define DMU_OT(byteswap, metadata) \
+        (DMU_OT_NEWTYPE | \
+        ((metadata) ? DMU_OT_METADATA : 0) | \
+        ((byteswap) & DMU_OT_BYTESWAP_MASK))
+
+#define DMU_OT_IS_VALID(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+        ((ot) & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS : \
+        (ot) < DMU_OT_NUMTYPES)
+
+#define DMU_OT_IS_METADATA(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+        ((ot) & DMU_OT_METADATA) : \
+        dmu_ot[(ot)].ot_metadata)
+
+#define DMU_OT_BYTESWAP(ot) (((ot) & DMU_OT_NEWTYPE) ? \
+        ((ot) & DMU_OT_BYTESWAP_MASK) : \
+        dmu_ot[(ot)].ot_byteswap)
+
 typedef enum dmu_object_type {
         DMU_OT_NONE,
         /* general: */
         DMU_OT_OBJECT_DIRECTORY,        /* ZAP */
         DMU_OT_OBJECT_ARRAY,            /* UINT64 */

@@ -137,11 +183,39 @@
         DMU_OT_DEDUP,                   /* fake dedup BP from ddt_bp_create() */
         DMU_OT_DEADLIST,                /* ZAP */
         DMU_OT_DEADLIST_HDR,            /* UINT64 */
         DMU_OT_DSL_CLONES,              /* ZAP */
         DMU_OT_BPOBJ_SUBOBJ,            /* UINT64 */
-        DMU_OT_NUMTYPES
+        /*
+         * Do not allocate new object types here. Doing so makes the on-disk
+         * format incompatible with any other format that uses the same object
+         * type number.
+         *
+         * When creating an object which does not have one of the above types
+         * use the DMU_OTN_* type with the correct byteswap and metadata
+         * values.
+         *
+         * The DMU_OTN_* types do not have entries in the dmu_ot table,
+         * use the DMU_OT_IS_METDATA() and DMU_OT_BYTESWAP() macros instead
+         * of indexing into dmu_ot directly (this works for both DMU_OT_* types
+         * and DMU_OTN_* types).
+         */
+        DMU_OT_NUMTYPES,
+
+        /*
+         * Names for valid types declared with DMU_OT().
+         */
+        DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE),
+        DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE),
+        DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE),
+        DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE),
+        DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE),
+        DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE),
+        DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE),
+        DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE),
+        DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE),
+        DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE),
 } dmu_object_type_t;
 
 typedef enum dmu_objset_type {
         DMU_OST_NONE,
         DMU_OST_META,

@@ -217,10 +291,13 @@
 /*
  * The names of zap entries in the DIRECTORY_OBJECT of the MOS.
  */
 #define DMU_POOL_DIRECTORY_OBJECT       1
 #define DMU_POOL_CONFIG                 "config"
+#define DMU_POOL_FEATURES_FOR_WRITE     "features_for_write"
+#define DMU_POOL_FEATURES_FOR_READ      "features_for_read"
+#define DMU_POOL_FEATURE_DESCRIPTIONS   "feature_descriptions"
 #define DMU_POOL_ROOT_DATASET           "root_dataset"
 #define DMU_POOL_SYNC_BPOBJ             "sync_bplist"
 #define DMU_POOL_ERRLOG_SCRUB           "errlog_scrub"
 #define DMU_POOL_ERRLOG_LAST            "errlog_last"
 #define DMU_POOL_SPARES                 "spares"

@@ -232,10 +309,11 @@
 #define DMU_POOL_DDT                    "DDT-%s-%s-%s"
 #define DMU_POOL_DDT_STATS              "DDT-statistics"
 #define DMU_POOL_CREATION_VERSION       "creation_version"
 #define DMU_POOL_SCAN                   "scan"
 #define DMU_POOL_FREE_BPOBJ             "free_bpobj"
+#define DMU_POOL_BPTREE_OBJ             "bptree_obj"
 
 /*
  * Allocate an object from this objset.  The range of object numbers
  * available is (0, DN_MAX_OBJECT).  Object 0 is the meta-dnode.
  *

@@ -492,11 +570,11 @@
 void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
     void *dcb_data);
 
 /*
  * Free up the data blocks for a defined range of a file.  If size is
- * zero, the range from offset to end-of-file is freed.
+ * -1, the range from offset to end-of-file is freed.
  */
 int dmu_free_range(objset_t *os, uint64_t object, uint64_t offset,
         uint64_t size, dmu_tx_t *tx);
 int dmu_free_long_range(objset_t *os, uint64_t object, uint64_t offset,
         uint64_t size);

@@ -562,16 +640,22 @@
 } dmu_object_info_t;
 
 typedef void arc_byteswap_func_t(void *buf, size_t size);
 
 typedef struct dmu_object_type_info {
-        arc_byteswap_func_t     *ot_byteswap;
+        dmu_object_byteswap_t   ot_byteswap;
         boolean_t               ot_metadata;
         char                    *ot_name;
 } dmu_object_type_info_t;
 
+typedef struct dmu_object_byteswap_info {
+        arc_byteswap_func_t     *ob_func;
+        char                    *ob_name;
+} dmu_object_byteswap_info_t;
+
 extern const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES];
+extern const dmu_object_byteswap_info_t dmu_ot_byteswap[DMU_BSWAP_NUMFUNCS];
 
 /*
  * Get information on a DMU object.
  *
  * Return 0 on success or ENOENT if object is not allocated.