Illumos #3552, #3564
[zfs.git] / include / sys / metaslab_impl.h
index 6c670a1..a36baed 100644 (file)
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #ifndef _SYS_METASLAB_IMPL_H
@@ -46,6 +49,7 @@ struct metaslab_class {
        uint64_t                mc_deferred;    /* total deferred frees */
        uint64_t                mc_space;       /* total space (alloc + free) */
        uint64_t                mc_dspace;      /* total deflated space */
+       kmutex_t                mc_fastwrite_lock;
 };
 
 struct metaslab_group {
@@ -63,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               */