--- old/usr/src/uts/common/fs/zfs/metaslab.c Mon Apr 7 00:45:25 2008 +++ new/usr/src/uts/common/fs/zfs/metaslab.c Mon Apr 7 00:45:25 2008 @@ -843,9 +843,12 @@ } DVA_SET_VDEV(&dva[d], vd->vdev_id); - DVA_SET_OFFSET(&dva[d], offset); - DVA_SET_GANG(&dva[d], 0); + if (vd->vdev_ops->vdev_op_grid != NULL) + DVA_SET_GRID(&dva[d], + vd->vdev_ops->vdev_op_grid(vd); DVA_SET_ASIZE(&dva[d], asize); + DVA_SET_GANG(&dva[d], 0); + DVA_SET_OFFSET(&dva[d], offset); return (0); } --- old/usr/src/uts/common/fs/zfs/space_map.c Mon Apr 7 00:45:25 2008 +++ new/usr/src/uts/common/fs/zfs/space_map.c Mon Apr 7 00:45:25 2008 @@ -180,7 +180,29 @@ 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; @@ -345,9 +367,18 @@ 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, --- old/usr/src/uts/common/fs/zfs/sys/space_map.h Mon Apr 7 00:45:26 2008 +++ new/usr/src/uts/common/fs/zfs/sys/space_map.h Mon Apr 7 00:45:26 2008 @@ -73,23 +73,29 @@ }; /* - * debug entry + * allocation/free entry * - * 1 3 10 50 - * ,---+--------+------------+---------------------------------. - * | 1 | action | syncpass | txg (lower bits) | - * `---+--------+------------+---------------------------------' - * 63 62 60 59 50 49 0 - * - * - * - * non-debug entry - * * 1 47 1 15 - * ,-----------------------------------------------------------. + * ,---+------------------------------+------+-----------------. * | 0 | offset (sm_shift units) | type | run | - * `-----------------------------------------------------------' + * `---+------------------------------+------+-----------------' * 63 62 17 16 15 0 + * + * special entry + * + * 1 1 6 56 + * ,---+---+----------+----------------------------------------. + * | 1 | 1 | action | | + * `---+---+----------+----------------------------------------' + * 63 62 61 56 55 0 + * + * debug entry + * + * 1 1 2 10 50 + * ,---+---+--------+----------+-------------------------------. + * | 1 | 0 | action | syncpass | txg (lower bits) | + * `---+---+--------+----------+-------------------------------' + * 63 62 61 60 59 50 49 0 */ /* All this stuff takes and returns bytes */ @@ -99,15 +105,19 @@ #define SM_TYPE_ENCODE(x) BF64_ENCODE(x, 15, 1) #define SM_OFFSET_DECODE(x) BF64_DECODE(x, 16, 47) #define SM_OFFSET_ENCODE(x) BF64_ENCODE(x, 16, 47) -#define SM_DEBUG_DECODE(x) BF64_DECODE(x, 63, 1) -#define SM_DEBUG_ENCODE(x) BF64_ENCODE(x, 63, 1) +#define SM_IS_SPECIAL(x) (BF64_DECODE(x, 62, 2) == 3) +#define SM_SPECIAL_ENCODE() BF64_ENCODE(3, 62, 2) +#define SM_IS_DEBUG(x) (BF64_DECODE(x, 62, 2) == 2) +#define SM_DEBUG_ENCODE() BF64_ENCODE(2, 62, 2) + +#define SM_SPECIAL_ACTION_DECODE(x) BF64_DECODE(x, 56, 6) +#define SM_SPECIAL_ACTION_ENCODE(x) BF64_ENCODE(x, 56, 6) + #define SM_DEBUG_ACTION_DECODE(x) BF64_DECODE(x, 60, 3) #define SM_DEBUG_ACTION_ENCODE(x) BF64_ENCODE(x, 60, 3) - #define SM_DEBUG_SYNCPASS_DECODE(x) BF64_DECODE(x, 50, 10) #define SM_DEBUG_SYNCPASS_ENCODE(x) BF64_ENCODE(x, 50, 10) - #define SM_DEBUG_TXG_DECODE(x) BF64_DECODE(x, 0, 50) #define SM_DEBUG_TXG_ENCODE(x) BF64_ENCODE(x, 0, 50) @@ -116,6 +126,8 @@ #define SM_ALLOC 0x0 #define SM_FREE 0x1 +#define SM_FOLD 0x01 + /* * The data for a given space map can be kept on blocks of any size. * Larger blocks entail fewer i/o operations, but they also cause the --- old/usr/src/uts/common/fs/zfs/sys/vdev_impl.h Mon Apr 7 00:45:26 2008 +++ new/usr/src/uts/common/fs/zfs/sys/vdev_impl.h Mon Apr 7 00:45:26 2008 @@ -64,7 +64,8 @@ typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize); typedef int vdev_io_start_func_t(zio_t *zio); typedef int vdev_io_done_func_t(zio_t *zio); -typedef void vdev_state_change_func_t(vdev_t *vd, int, int); +typedef void vdev_state_change_func_t(vdev_t *vd, int fauled, int degraded); +typedef uint8_t vdev_grid_func_t(vdev_t *vd); typedef struct vdev_ops { vdev_open_func_t *vdev_op_open; @@ -74,6 +75,7 @@ vdev_io_start_func_t *vdev_op_io_start; vdev_io_done_func_t *vdev_op_io_done; vdev_state_change_func_t *vdev_op_state_change; + vdev_grid_func_t *vdev_op_grid; char vdev_op_type[16]; boolean_t vdev_op_leaf; } vdev_ops_t; --- old/usr/src/uts/common/fs/zfs/vdev_disk.c Mon Apr 7 00:45:26 2008 +++ new/usr/src/uts/common/fs/zfs/vdev_disk.c Mon Apr 7 00:45:26 2008 @@ -555,6 +555,7 @@ vdev_disk_io_start, vdev_disk_io_done, NULL, + NULL, VDEV_TYPE_DISK, /* name of this vdev type */ B_TRUE /* leaf vdev */ }; --- old/usr/src/uts/common/fs/zfs/vdev_file.c Mon Apr 7 00:45:27 2008 +++ new/usr/src/uts/common/fs/zfs/vdev_file.c Mon Apr 7 00:45:27 2008 @@ -316,6 +316,7 @@ vdev_file_io_start, vdev_file_io_done, NULL, + NULL, VDEV_TYPE_FILE, /* name of this vdev type */ B_TRUE /* leaf vdev */ }; --- old/usr/src/uts/common/fs/zfs/vdev_mirror.c Mon Apr 7 00:45:27 2008 +++ new/usr/src/uts/common/fs/zfs/vdev_mirror.c Mon Apr 7 00:45:27 2008 @@ -467,6 +467,7 @@ vdev_mirror_io_start, vdev_mirror_io_done, vdev_mirror_state_change, + NULL, VDEV_TYPE_MIRROR, /* name of this vdev type */ B_FALSE /* not a leaf vdev */ }; @@ -479,6 +480,7 @@ vdev_mirror_io_start, vdev_mirror_io_done, vdev_mirror_state_change, + NULL, VDEV_TYPE_REPLACING, /* name of this vdev type */ B_FALSE /* not a leaf vdev */ }; @@ -491,6 +493,7 @@ vdev_mirror_io_start, vdev_mirror_io_done, vdev_mirror_state_change, + NULL, VDEV_TYPE_SPARE, /* name of this vdev type */ B_FALSE /* not a leaf vdev */ }; --- old/usr/src/uts/common/fs/zfs/vdev_missing.c Mon Apr 7 00:45:28 2008 +++ new/usr/src/uts/common/fs/zfs/vdev_missing.c Mon Apr 7 00:45:28 2008 @@ -91,6 +91,7 @@ vdev_missing_io_start, vdev_missing_io_done, NULL, + NULL, VDEV_TYPE_MISSING, /* name of this vdev type */ B_TRUE /* leaf vdev */ }; --- old/usr/src/uts/common/fs/zfs/vdev_raidz.c Mon Apr 7 00:45:28 2008 +++ new/usr/src/uts/common/fs/zfs/vdev_raidz.c Mon Apr 7 00:45:28 2008 @@ -1226,6 +1226,13 @@ vdev_set_state(vd, B_FALSE, VDEV_STATE_HEALTHY, VDEV_AUX_NONE); } +static uint8_t +vdev_raidz_grid(vdev_t *vd) +{ + ASSERT(vd->vdev_nparity - 1 <= 1); + return (((vd->vdev_nparity - 1) << 6) | vd->vdev_children); +} + vdev_ops_t vdev_raidz_ops = { vdev_raidz_open, vdev_raidz_close, @@ -1234,6 +1241,7 @@ vdev_raidz_io_start, vdev_raidz_io_done, vdev_raidz_state_change, + vdev_raidz_grid, VDEV_TYPE_RAIDZ, /* name of this vdev type */ B_FALSE /* not a leaf vdev */ }; --- old/usr/src/uts/common/fs/zfs/vdev_root.c Mon Apr 7 00:45:28 2008 +++ new/usr/src/uts/common/fs/zfs/vdev_root.c Mon Apr 7 00:45:28 2008 @@ -125,6 +125,7 @@ NULL, /* io_start - not applicable to the root */ NULL, /* io_done - not applicable to the root */ vdev_root_state_change, + NULL, VDEV_TYPE_ROOT, /* name of this vdev type */ B_FALSE /* not a leaf vdev */ };