X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fspace_map.c;h=9c0cdb6beeccd947c47773d043a311dd6081b8bc;hb=30b92c1de68ced4bee235f879791ee316314a197;hp=1cdacc81da95a053b11b27aaa80101e30ad3954d;hpb=fb5f0bc83330c8a0236c4d34a23723ac1974971a;p=zfs.git diff --git a/module/zfs/space_map.c b/module/zfs/space_map.c index 1cdacc8..9c0cdb6 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,19 +116,33 @@ 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 = kmem_alloc(sizeof (*ss), KM_PUSHPAGE); ss->ss_start = start; ss->ss_end = end; 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 = kmem_alloc(sizeof (*newseg), KM_PUSHPAGE); 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; } @@ -235,8 +258,10 @@ space_map_load_wait(space_map_t *sm) { ASSERT(MUTEX_HELD(sm->sm_lock)); - while (sm->sm_loading) + while (sm->sm_loading) { + ASSERT(!sm->sm_loaded); cv_wait(&sm->sm_load_cv, sm->sm_lock); + } } /* @@ -253,11 +278,8 @@ space_map_load(space_map_t *sm, space_map_ops_t *ops, uint8_t maptype, int error = 0; ASSERT(MUTEX_HELD(sm->sm_lock)); - - space_map_load_wait(sm); - - if (sm->sm_loaded) - return (0); + ASSERT(!sm->sm_loaded); + ASSERT(!sm->sm_loading); sm->sm_loading = B_TRUE; end = smo->smo_objsize; @@ -288,7 +310,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 +365,13 @@ space_map_unload(space_map_t *sm) } uint64_t +space_map_maxsize(space_map_t *sm) +{ + ASSERT(sm->sm_ops != NULL); + return (sm->sm_ops->smop_max(sm)); +} + +uint64_t space_map_alloc(space_map_t *sm, uint64_t size) { uint64_t start; @@ -521,7 +551,7 @@ space_map_ref_add_node(avl_tree_t *t, uint64_t offset, int64_t refcnt) { space_ref_t *sr; - sr = kmem_alloc(sizeof (*sr), KM_SLEEP); + sr = kmem_alloc(sizeof (*sr), KM_PUSHPAGE); sr->sr_offset = offset; sr->sr_refcnt = refcnt;