diff options
author | Brian Behlendorf <behlendorf1@llnl.gov> | 2009-07-02 22:44:48 +0000 |
---|---|---|
committer | Brian Behlendorf <behlendorf1@llnl.gov> | 2009-07-02 22:44:48 +0000 |
commit | 9babb37438b58e77bad04e820d5702e15b79e6a6 (patch) | |
tree | e369da81095eca3fc155b0c02bdd4a9f06506781 /module/zfs/space_map.c | |
parent | d164b2093561a9771db07346e6fffc9ca19427a2 (diff) | |
download | src-9babb37438b58e77bad04e820d5702e15b79e6a6.tar.gz src-9babb37438b58e77bad04e820d5702e15b79e6a6.zip |
Diffstat (limited to 'module/zfs/space_map.c')
-rw-r--r-- | module/zfs/space_map.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/module/zfs/space_map.c b/module/zfs/space_map.c index 1cdacc81da95..75b55d5c1ca7 100644 --- a/module/zfs/space_map.c +++ b/module/zfs/space_map.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -116,12 +116,23 @@ space_map_add(space_map_t *sm, uint64_t start, uint64_t size) if (merge_before && merge_after) { avl_remove(&sm->sm_root, ss_before); + if (sm->sm_pp_root) { + avl_remove(sm->sm_pp_root, ss_before); + avl_remove(sm->sm_pp_root, ss_after); + } ss_after->ss_start = ss_before->ss_start; kmem_free(ss_before, sizeof (*ss_before)); + ss = ss_after; } else if (merge_before) { ss_before->ss_end = end; + if (sm->sm_pp_root) + avl_remove(sm->sm_pp_root, ss_before); + ss = ss_before; } else if (merge_after) { ss_after->ss_start = start; + if (sm->sm_pp_root) + avl_remove(sm->sm_pp_root, ss_after); + ss = ss_after; } else { ss = kmem_alloc(sizeof (*ss), KM_SLEEP); ss->ss_start = start; @@ -129,6 +140,9 @@ space_map_add(space_map_t *sm, uint64_t start, uint64_t size) avl_insert(&sm->sm_root, ss, where); } + if (sm->sm_pp_root) + avl_add(sm->sm_pp_root, ss); + sm->sm_space += size; } @@ -163,12 +177,17 @@ space_map_remove(space_map_t *sm, uint64_t start, uint64_t size) left_over = (ss->ss_start != start); right_over = (ss->ss_end != end); + if (sm->sm_pp_root) + avl_remove(sm->sm_pp_root, ss); + if (left_over && right_over) { newseg = kmem_alloc(sizeof (*newseg), KM_SLEEP); newseg->ss_start = end; newseg->ss_end = ss->ss_end; ss->ss_end = start; avl_insert_here(&sm->sm_root, newseg, ss, AVL_AFTER); + if (sm->sm_pp_root) + avl_add(sm->sm_pp_root, newseg); } else if (left_over) { ss->ss_end = start; } else if (right_over) { @@ -176,8 +195,12 @@ space_map_remove(space_map_t *sm, uint64_t start, uint64_t size) } else { avl_remove(&sm->sm_root, ss); kmem_free(ss, sizeof (*ss)); + ss = NULL; } + if (sm->sm_pp_root && ss != NULL) + avl_add(sm->sm_pp_root, ss); + sm->sm_space -= size; } @@ -288,7 +311,8 @@ space_map_load(space_map_t *sm, space_map_ops_t *ops, uint8_t maptype, smo->smo_object, offset, size); mutex_exit(sm->sm_lock); - error = dmu_read(os, smo->smo_object, offset, size, entry_map); + error = dmu_read(os, smo->smo_object, offset, size, entry_map, + DMU_READ_PREFETCH); mutex_enter(sm->sm_lock); if (error != 0) break; @@ -342,6 +366,15 @@ space_map_unload(space_map_t *sm) } uint64_t +space_map_maxsize(space_map_t *sm) +{ + if (sm->sm_loaded && sm->sm_ops != NULL) + return (sm->sm_ops->smop_max(sm)); + else + return (-1ULL); +} + +uint64_t space_map_alloc(space_map_t *sm, uint64_t size) { uint64_t start; |