1789Sahrens /* 2789Sahrens * CDDL HEADER START 3789Sahrens * 4789Sahrens * The contents of this file are subject to the terms of the 51732Sbonwick * Common Development and Distribution License (the "License"). 61732Sbonwick * You may not use this file except in compliance with the License. 7789Sahrens * 8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9789Sahrens * or http://www.opensolaris.org/os/licensing. 10789Sahrens * See the License for the specific language governing permissions 11789Sahrens * and limitations under the License. 12789Sahrens * 13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15789Sahrens * If applicable, add the following below this CDDL HEADER, with the 16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18789Sahrens * 19789Sahrens * CDDL HEADER END 20789Sahrens */ 21789Sahrens /* 229480SGeorge.Wilson@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23789Sahrens * Use is subject to license terms. 24789Sahrens */ 25789Sahrens 26789Sahrens #ifndef _SYS_SPACE_MAP_H 27789Sahrens #define _SYS_SPACE_MAP_H 28789Sahrens 29789Sahrens #include <sys/avl.h> 30789Sahrens #include <sys/dmu.h> 31789Sahrens 32789Sahrens #ifdef __cplusplus 33789Sahrens extern "C" { 34789Sahrens #endif 35789Sahrens 361732Sbonwick typedef struct space_map_ops space_map_ops_t; 371732Sbonwick 38789Sahrens typedef struct space_map { 391732Sbonwick avl_tree_t sm_root; /* AVL tree of map segments */ 401732Sbonwick uint64_t sm_space; /* sum of all segments in the map */ 411732Sbonwick uint64_t sm_start; /* start of map */ 421732Sbonwick uint64_t sm_size; /* size of map */ 431732Sbonwick uint8_t sm_shift; /* unit shift */ 441732Sbonwick uint8_t sm_pad[3]; /* unused */ 451732Sbonwick uint8_t sm_loaded; /* map loaded? */ 461732Sbonwick uint8_t sm_loading; /* map loading? */ 471732Sbonwick kcondvar_t sm_load_cv; /* map load completion */ 481732Sbonwick space_map_ops_t *sm_ops; /* space map block picker ops vector */ 499480SGeorge.Wilson@Sun.COM avl_tree_t *sm_pp_root; /* picker-private AVL tree */ 501732Sbonwick void *sm_ppd; /* picker-private data */ 51789Sahrens kmutex_t *sm_lock; /* pointer to lock that protects map */ 52789Sahrens } space_map_t; 53789Sahrens 54789Sahrens typedef struct space_seg { 55789Sahrens avl_node_t ss_node; /* AVL node */ 569480SGeorge.Wilson@Sun.COM avl_node_t ss_pp_node; /* AVL picker-private node */ 57789Sahrens uint64_t ss_start; /* starting offset of this segment */ 58789Sahrens uint64_t ss_end; /* ending offset (non-inclusive) */ 59789Sahrens } space_seg_t; 60789Sahrens 618241SJeff.Bonwick@Sun.COM typedef struct space_ref { 628241SJeff.Bonwick@Sun.COM avl_node_t sr_node; /* AVL node */ 638241SJeff.Bonwick@Sun.COM uint64_t sr_offset; /* offset (start or end) */ 648241SJeff.Bonwick@Sun.COM int64_t sr_refcnt; /* associated reference count */ 658241SJeff.Bonwick@Sun.COM } space_ref_t; 668241SJeff.Bonwick@Sun.COM 67789Sahrens typedef struct space_map_obj { 68789Sahrens uint64_t smo_object; /* on-disk space map object */ 69789Sahrens uint64_t smo_objsize; /* size of the object */ 70789Sahrens uint64_t smo_alloc; /* space allocated from the map */ 71789Sahrens } space_map_obj_t; 72789Sahrens 731732Sbonwick struct space_map_ops { 741732Sbonwick void (*smop_load)(space_map_t *sm); 751732Sbonwick void (*smop_unload)(space_map_t *sm); 761732Sbonwick uint64_t (*smop_alloc)(space_map_t *sm, uint64_t size); 771732Sbonwick void (*smop_claim)(space_map_t *sm, uint64_t start, uint64_t size); 781732Sbonwick void (*smop_free)(space_map_t *sm, uint64_t start, uint64_t size); 799480SGeorge.Wilson@Sun.COM uint64_t (*smop_max)(space_map_t *sm); 80*11146SGeorge.Wilson@Sun.COM boolean_t (*smop_fragmented)(space_map_t *sm); 811732Sbonwick }; 821732Sbonwick 83789Sahrens /* 84789Sahrens * debug entry 85789Sahrens * 86789Sahrens * 1 3 10 50 87789Sahrens * ,---+--------+------------+---------------------------------. 88789Sahrens * | 1 | action | syncpass | txg (lower bits) | 89789Sahrens * `---+--------+------------+---------------------------------' 90789Sahrens * 63 62 60 59 50 49 0 91789Sahrens * 92789Sahrens * 93789Sahrens * 94789Sahrens * non-debug entry 95789Sahrens * 96789Sahrens * 1 47 1 15 97789Sahrens * ,-----------------------------------------------------------. 98789Sahrens * | 0 | offset (sm_shift units) | type | run | 99789Sahrens * `-----------------------------------------------------------' 100789Sahrens * 63 62 17 16 15 0 101789Sahrens */ 102789Sahrens 103789Sahrens /* All this stuff takes and returns bytes */ 104789Sahrens #define SM_RUN_DECODE(x) (BF64_DECODE(x, 0, 15) + 1) 105789Sahrens #define SM_RUN_ENCODE(x) BF64_ENCODE((x) - 1, 0, 15) 106789Sahrens #define SM_TYPE_DECODE(x) BF64_DECODE(x, 15, 1) 107789Sahrens #define SM_TYPE_ENCODE(x) BF64_ENCODE(x, 15, 1) 108789Sahrens #define SM_OFFSET_DECODE(x) BF64_DECODE(x, 16, 47) 109789Sahrens #define SM_OFFSET_ENCODE(x) BF64_ENCODE(x, 16, 47) 110789Sahrens #define SM_DEBUG_DECODE(x) BF64_DECODE(x, 63, 1) 111789Sahrens #define SM_DEBUG_ENCODE(x) BF64_ENCODE(x, 63, 1) 112789Sahrens 113789Sahrens #define SM_DEBUG_ACTION_DECODE(x) BF64_DECODE(x, 60, 3) 114789Sahrens #define SM_DEBUG_ACTION_ENCODE(x) BF64_ENCODE(x, 60, 3) 115789Sahrens 116789Sahrens #define SM_DEBUG_SYNCPASS_DECODE(x) BF64_DECODE(x, 50, 10) 117789Sahrens #define SM_DEBUG_SYNCPASS_ENCODE(x) BF64_ENCODE(x, 50, 10) 118789Sahrens 119789Sahrens #define SM_DEBUG_TXG_DECODE(x) BF64_DECODE(x, 0, 50) 120789Sahrens #define SM_DEBUG_TXG_ENCODE(x) BF64_ENCODE(x, 0, 50) 121789Sahrens 122789Sahrens #define SM_RUN_MAX SM_RUN_DECODE(~0ULL) 123789Sahrens 124789Sahrens #define SM_ALLOC 0x0 125789Sahrens #define SM_FREE 0x1 126789Sahrens 127789Sahrens /* 128789Sahrens * The data for a given space map can be kept on blocks of any size. 129789Sahrens * Larger blocks entail fewer i/o operations, but they also cause the 130789Sahrens * DMU to keep more data in-core, and also to waste more i/o bandwidth 131789Sahrens * when only a few blocks have changed since the last transaction group. 132789Sahrens * This could use a lot more research, but for now, set the freelist 133789Sahrens * block size to 4k (2^12). 134789Sahrens */ 135789Sahrens #define SPACE_MAP_BLOCKSHIFT 12 136789Sahrens 137789Sahrens typedef void space_map_func_t(space_map_t *sm, uint64_t start, uint64_t size); 138789Sahrens 139789Sahrens extern void space_map_create(space_map_t *sm, uint64_t start, uint64_t size, 1401732Sbonwick uint8_t shift, kmutex_t *lp); 141789Sahrens extern void space_map_destroy(space_map_t *sm); 142789Sahrens extern void space_map_add(space_map_t *sm, uint64_t start, uint64_t size); 143789Sahrens extern void space_map_remove(space_map_t *sm, uint64_t start, uint64_t size); 1448241SJeff.Bonwick@Sun.COM extern boolean_t space_map_contains(space_map_t *sm, 1458241SJeff.Bonwick@Sun.COM uint64_t start, uint64_t size); 146789Sahrens extern void space_map_vacate(space_map_t *sm, 147789Sahrens space_map_func_t *func, space_map_t *mdest); 1481732Sbonwick extern void space_map_walk(space_map_t *sm, 149789Sahrens space_map_func_t *func, space_map_t *mdest); 150789Sahrens 1511732Sbonwick extern void space_map_load_wait(space_map_t *sm); 1521732Sbonwick extern int space_map_load(space_map_t *sm, space_map_ops_t *ops, 1531732Sbonwick uint8_t maptype, space_map_obj_t *smo, objset_t *os); 1541732Sbonwick extern void space_map_unload(space_map_t *sm); 1551732Sbonwick 1561732Sbonwick extern uint64_t space_map_alloc(space_map_t *sm, uint64_t size); 1571732Sbonwick extern void space_map_claim(space_map_t *sm, uint64_t start, uint64_t size); 1581732Sbonwick extern void space_map_free(space_map_t *sm, uint64_t start, uint64_t size); 1599480SGeorge.Wilson@Sun.COM extern uint64_t space_map_maxsize(space_map_t *sm); 1601732Sbonwick 1611732Sbonwick extern void space_map_sync(space_map_t *sm, uint8_t maptype, 1621732Sbonwick space_map_obj_t *smo, objset_t *os, dmu_tx_t *tx); 1631732Sbonwick extern void space_map_truncate(space_map_obj_t *smo, 164789Sahrens objset_t *os, dmu_tx_t *tx); 165789Sahrens 1668241SJeff.Bonwick@Sun.COM extern void space_map_ref_create(avl_tree_t *t); 1678241SJeff.Bonwick@Sun.COM extern void space_map_ref_destroy(avl_tree_t *t); 1688241SJeff.Bonwick@Sun.COM extern void space_map_ref_add_seg(avl_tree_t *t, 1698241SJeff.Bonwick@Sun.COM uint64_t start, uint64_t end, int64_t refcnt); 1708241SJeff.Bonwick@Sun.COM extern void space_map_ref_add_map(avl_tree_t *t, 1718241SJeff.Bonwick@Sun.COM space_map_t *sm, int64_t refcnt); 1728241SJeff.Bonwick@Sun.COM extern void space_map_ref_generate_map(avl_tree_t *t, 1738241SJeff.Bonwick@Sun.COM space_map_t *sm, int64_t minref); 1748241SJeff.Bonwick@Sun.COM 175789Sahrens #ifdef __cplusplus 176789Sahrens } 177789Sahrens #endif 178789Sahrens 179789Sahrens #endif /* _SYS_SPACE_MAP_H */ 180