Changeset View
Changeset View
Standalone View
Standalone View
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
Show First 20 Lines • Show All 1,114 Lines • ▼ Show 20 Lines | metaslab_rangesize_compare(const void *x1, const void *x2) | ||||
if (r1->rs_start > r2->rs_start) | if (r1->rs_start > r2->rs_start) | ||||
return (1); | return (1); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Create any block allocator specific components. The current allocators | |||||
* rely on using both a size-ordered range_tree_t and an array of uint64_t's. | |||||
*/ | |||||
static void | |||||
metaslab_rt_create(range_tree_t *rt, void *arg) | |||||
{ | |||||
metaslab_t *msp = arg; | |||||
ASSERT3P(rt->rt_arg, ==, msp); | |||||
ASSERT(msp->ms_allocatable == NULL); | |||||
avl_create(&msp->ms_allocatable_by_size, metaslab_rangesize_compare, | |||||
sizeof (range_seg_t), offsetof(range_seg_t, rs_pp_node)); | |||||
} | |||||
/* | |||||
* Destroy the block allocator specific components. | |||||
*/ | |||||
static void | |||||
metaslab_rt_destroy(range_tree_t *rt, void *arg) | |||||
{ | |||||
metaslab_t *msp = arg; | |||||
ASSERT3P(rt->rt_arg, ==, msp); | |||||
ASSERT3P(msp->ms_allocatable, ==, rt); | |||||
ASSERT0(avl_numnodes(&msp->ms_allocatable_by_size)); | |||||
avl_destroy(&msp->ms_allocatable_by_size); | |||||
} | |||||
static void | |||||
metaslab_rt_add(range_tree_t *rt, range_seg_t *rs, void *arg) | |||||
{ | |||||
metaslab_t *msp = arg; | |||||
ASSERT3P(rt->rt_arg, ==, msp); | |||||
ASSERT3P(msp->ms_allocatable, ==, rt); | |||||
VERIFY(!msp->ms_condensing); | |||||
avl_add(&msp->ms_allocatable_by_size, rs); | |||||
} | |||||
static void | |||||
metaslab_rt_remove(range_tree_t *rt, range_seg_t *rs, void *arg) | |||||
{ | |||||
metaslab_t *msp = arg; | |||||
ASSERT3P(rt->rt_arg, ==, msp); | |||||
ASSERT3P(msp->ms_allocatable, ==, rt); | |||||
VERIFY(!msp->ms_condensing); | |||||
avl_remove(&msp->ms_allocatable_by_size, rs); | |||||
} | |||||
static void | |||||
metaslab_rt_vacate(range_tree_t *rt, void *arg) | |||||
{ | |||||
metaslab_t *msp = arg; | |||||
ASSERT3P(rt->rt_arg, ==, msp); | |||||
ASSERT3P(msp->ms_allocatable, ==, rt); | |||||
/* | |||||
* Normally one would walk the tree freeing nodes along the way. | |||||
* Since the nodes are shared with the range trees we can avoid | |||||
* walking all nodes and just reinitialize the avl tree. The nodes | |||||
* will be freed by the range tree, so we don't want to free them here. | |||||
*/ | |||||
avl_create(&msp->ms_allocatable_by_size, metaslab_rangesize_compare, | |||||
sizeof (range_seg_t), offsetof(range_seg_t, rs_pp_node)); | |||||
} | |||||
static range_tree_ops_t metaslab_rt_ops = { | |||||
metaslab_rt_create, | |||||
metaslab_rt_destroy, | |||||
metaslab_rt_add, | |||||
metaslab_rt_remove, | |||||
metaslab_rt_vacate | |||||
}; | |||||
/* | |||||
* ========================================================================== | * ========================================================================== | ||||
* Common allocator routines | * Common allocator routines | ||||
* ========================================================================== | * ========================================================================== | ||||
*/ | */ | ||||
/* | /* | ||||
* Return the maximum contiguous segment within the metaslab. | * Return the maximum contiguous segment within the metaslab. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 359 Lines • ▼ Show 20 Lines | metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg, | ||||
/* | /* | ||||
* We create the main range tree here, but we don't create the | * We create the main range tree here, but we don't create the | ||||
* other range trees until metaslab_sync_done(). This serves | * other range trees until metaslab_sync_done(). This serves | ||||
* two purposes: it allows metaslab_sync_done() to detect the | * two purposes: it allows metaslab_sync_done() to detect the | ||||
* addition of new space; and for debugging, it ensures that we'd | * addition of new space; and for debugging, it ensures that we'd | ||||
* data fault on any attempt to use this metaslab before it's ready. | * data fault on any attempt to use this metaslab before it's ready. | ||||
*/ | */ | ||||
ms->ms_allocatable = range_tree_create(&metaslab_rt_ops, ms); | ms->ms_allocatable = range_tree_create_impl(&rt_avl_ops, &ms->ms_allocatable_by_size, | ||||
metaslab_rangesize_compare, 0); | |||||
metaslab_group_add(mg, ms); | metaslab_group_add(mg, ms); | ||||
metaslab_set_fragmentation(ms); | metaslab_set_fragmentation(ms); | ||||
/* | /* | ||||
* If we're opening an existing pool (txg == 0) or creating | * If we're opening an existing pool (txg == 0) or creating | ||||
* a new one (txg == TXG_INITIAL), all space is available now. | * a new one (txg == TXG_INITIAL), all space is available now. | ||||
* If we're adding space to an existing pool, the new space | * If we're adding space to an existing pool, the new space | ||||
▲ Show 20 Lines • Show All 2,446 Lines • Show Last 20 Lines |