Print this page
expandable RAID-Z

@@ -178,11 +178,33 @@
         }
 
         sm->sm_space -= size;
 }
 
+
+
 int
+space_map_fold(space_map_t *sm, uint8_t oldwidth, uint8_t newwidth)
+{
+        space_seg_t *ss;
+        uint64_t d, r;
+
+        ASSERT(MUTEX_HELD(sm->sm_lock));
+
+        for (ss = avl_first(&sm->sm_root); ss != NULL;
+            ss = AVL_NEXT(&sm->sm_root, ss)) {
+                d = ss->ss_start / oldwidth;
+                r = ss->ss_start % oldwidth;
+                ss->ss_start = d * newwidth + r;
+
+                d = ss->ss_end / oldwidth;
+                r = ss->ss_end % oldwidth;
+                ss->ss_end = d * newwidth + r;
+        }
+}
+
+int
 space_map_contains(space_map_t *sm, uint64_t start, uint64_t size)
 {
         avl_index_t where;
         space_seg_t ssearch, *ss;
         uint64_t end = start + size;

@@ -343,13 +365,22 @@
 
                 entry_map_end = entry_map + (size / sizeof (uint64_t));
                 for (entry = entry_map; entry < entry_map_end; entry++) {
                         uint64_t e = *entry;
 
-                        if (SM_DEBUG_DECODE(e))         /* Skip debug entries */
+                        if (SM_IS_DEBUG(e))             /* Skip debug entries */
                                 continue;
 
+                        if (SM_IS_SPECIAL(e)) {
+                                uint8_t oldwidth, newwidth;
+                                ASSERT(SM_SPECIAL_ACTION_DECODE(e) == SM_FOLD);
+                                oldwidth = BF64_ENCODE(e, 0, 8);
+                                newwidth = BF64_ENCODE(e, 8, 8);
+                                space_map_fold(sm, oldwidth, newwidth);
+                                continue;
+                        }
+
                         (SM_TYPE_DECODE(e) == maptype ?
                             space_map_add : space_map_remove)(sm,
                             (SM_OFFSET_DECODE(e) << sm->sm_shift) + mapstart,
                             SM_RUN_DECODE(e) << sm->sm_shift);
                 }