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);
}