Illumos #3552, #3564
[zfs.git] / include / sys / metaslab_impl.h
index 386f624..a36baed 100644 (file)
@@ -67,20 +67,38 @@ struct metaslab_group {
 };
 
 /*
- * Each metaslab's free space is tracked in space map object in the MOS,
- * which is only updated in syncing context.  Each time we sync a txg,
+ * Each metaslab maintains an in-core free map (ms_map) that contains the
+ * current list of free segments. As blocks are allocated, the allocated
+ * segment is removed from the ms_map and added to a per txg allocation map.
+ * As blocks are freed, they are added to the per txg free map. These per
+ * txg maps allow us to process all allocations and frees in syncing context
+ * where it is safe to update the on-disk space maps.
+ *
+ * Each metaslab's free space is tracked in a space map object in the MOS,
+ * which is only updated in syncing context. Each time we sync a txg,
  * we append the allocs and frees from that txg to the space map object.
  * When the txg is done syncing, metaslab_sync_done() updates ms_smo
- * to ms_smo_syncing.  Everything in ms_smo is always safe to allocate.
+ * to ms_smo_syncing. Everything in ms_smo is always safe to allocate.
+ *
+ * To load the in-core free map we read the space map object from disk.
+ * This object contains a series of alloc and free records that are
+ * combined to make up the list of all free segments in this metaslab. These
+ * segments are represented in-core by the ms_map and are stored in an
+ * AVL tree.
+ *
+ * As the space map objects grows (as a result of the appends) it will
+ * eventually become space-inefficient. When the space map object is
+ * zfs_condense_pct/100 times the size of the minimal on-disk representation,
+ * we rewrite it in its minimized form.
  */
 struct metaslab {
        kmutex_t        ms_lock;        /* metaslab lock                */
        space_map_obj_t ms_smo;         /* synced space map object      */
        space_map_obj_t ms_smo_syncing; /* syncing space map object     */
-       space_map_t     ms_allocmap[TXG_SIZE];  /* allocated this txg   */
-       space_map_t     ms_freemap[TXG_SIZE];   /* freed this txg       */
-       space_map_t     ms_defermap[TXG_DEFER_SIZE]; /* deferred frees  */
-       space_map_t     ms_map;         /* in-core free space map       */
+       space_map_t     *ms_allocmap[TXG_SIZE]; /* allocated this txg   */
+       space_map_t     *ms_freemap[TXG_SIZE];  /* freed this txg       */
+       space_map_t     *ms_defermap[TXG_DEFER_SIZE];   /* deferred frees */
+       space_map_t     *ms_map;        /* in-core free space map       */
        int64_t         ms_deferspace;  /* sum of ms_defermap[] space   */
        uint64_t        ms_weight;      /* weight vs. others in group   */
        metaslab_group_t *ms_group;     /* metaslab group               */