1fa9e4066Sahrens /* 2fa9e4066Sahrens * CDDL HEADER START 3fa9e4066Sahrens * 4fa9e4066Sahrens * The contents of this file are subject to the terms of the 5ecc2d604Sbonwick * Common Development and Distribution License (the "License"). 6ecc2d604Sbonwick * You may not use this file except in compliance with the License. 7fa9e4066Sahrens * 8fa9e4066Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e4066Sahrens * or http://www.opensolaris.org/os/licensing. 10fa9e4066Sahrens * See the License for the specific language governing permissions 11fa9e4066Sahrens * and limitations under the License. 12fa9e4066Sahrens * 13fa9e4066Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e4066Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e4066Sahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e4066Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e4066Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e4066Sahrens * 19fa9e4066Sahrens * CDDL HEADER END 20fa9e4066Sahrens */ 21fa9e4066Sahrens /* 22*d6e555bdSGeorge Wilson * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23fa9e4066Sahrens * Use is subject to license terms. 24fa9e4066Sahrens */ 25fa9e4066Sahrens 26fa9e4066Sahrens #ifndef _SYS_SPACE_MAP_H 27fa9e4066Sahrens #define _SYS_SPACE_MAP_H 28fa9e4066Sahrens 29fa9e4066Sahrens #include <sys/avl.h> 30fa9e4066Sahrens #include <sys/dmu.h> 31fa9e4066Sahrens 32fa9e4066Sahrens #ifdef __cplusplus 33fa9e4066Sahrens extern "C" { 34fa9e4066Sahrens #endif 35fa9e4066Sahrens 36ecc2d604Sbonwick typedef struct space_map_ops space_map_ops_t; 37ecc2d604Sbonwick 38fa9e4066Sahrens typedef struct space_map { 39ecc2d604Sbonwick avl_tree_t sm_root; /* AVL tree of map segments */ 40ecc2d604Sbonwick uint64_t sm_space; /* sum of all segments in the map */ 41ecc2d604Sbonwick uint64_t sm_start; /* start of map */ 42ecc2d604Sbonwick uint64_t sm_size; /* size of map */ 43ecc2d604Sbonwick uint8_t sm_shift; /* unit shift */ 44ecc2d604Sbonwick uint8_t sm_pad[3]; /* unused */ 45ecc2d604Sbonwick uint8_t sm_loaded; /* map loaded? */ 46ecc2d604Sbonwick uint8_t sm_loading; /* map loading? */ 47ecc2d604Sbonwick kcondvar_t sm_load_cv; /* map load completion */ 48ecc2d604Sbonwick space_map_ops_t *sm_ops; /* space map block picker ops vector */ 49*d6e555bdSGeorge Wilson avl_tree_t *sm_pp_root; /* picker-private AVL tree */ 50ecc2d604Sbonwick void *sm_ppd; /* picker-private data */ 51fa9e4066Sahrens kmutex_t *sm_lock; /* pointer to lock that protects map */ 52fa9e4066Sahrens } space_map_t; 53fa9e4066Sahrens 54fa9e4066Sahrens typedef struct space_seg { 55fa9e4066Sahrens avl_node_t ss_node; /* AVL node */ 56*d6e555bdSGeorge Wilson avl_node_t ss_pp_node; /* AVL picker-private node */ 57fa9e4066Sahrens uint64_t ss_start; /* starting offset of this segment */ 58fa9e4066Sahrens uint64_t ss_end; /* ending offset (non-inclusive) */ 59fa9e4066Sahrens } space_seg_t; 60fa9e4066Sahrens 618ad4d6ddSJeff Bonwick typedef struct space_ref { 628ad4d6ddSJeff Bonwick avl_node_t sr_node; /* AVL node */ 638ad4d6ddSJeff Bonwick uint64_t sr_offset; /* offset (start or end) */ 648ad4d6ddSJeff Bonwick int64_t sr_refcnt; /* associated reference count */ 658ad4d6ddSJeff Bonwick } space_ref_t; 668ad4d6ddSJeff Bonwick 67fa9e4066Sahrens typedef struct space_map_obj { 68fa9e4066Sahrens uint64_t smo_object; /* on-disk space map object */ 69fa9e4066Sahrens uint64_t smo_objsize; /* size of the object */ 70fa9e4066Sahrens uint64_t smo_alloc; /* space allocated from the map */ 71fa9e4066Sahrens } space_map_obj_t; 72fa9e4066Sahrens 73ecc2d604Sbonwick struct space_map_ops { 74ecc2d604Sbonwick void (*smop_load)(space_map_t *sm); 75ecc2d604Sbonwick void (*smop_unload)(space_map_t *sm); 76ecc2d604Sbonwick uint64_t (*smop_alloc)(space_map_t *sm, uint64_t size); 77ecc2d604Sbonwick void (*smop_claim)(space_map_t *sm, uint64_t start, uint64_t size); 78ecc2d604Sbonwick void (*smop_free)(space_map_t *sm, uint64_t start, uint64_t size); 79*d6e555bdSGeorge Wilson uint64_t (*smop_max)(space_map_t *sm); 80ecc2d604Sbonwick }; 81ecc2d604Sbonwick 82fa9e4066Sahrens /* 83fa9e4066Sahrens * debug entry 84fa9e4066Sahrens * 85fa9e4066Sahrens * 1 3 10 50 86fa9e4066Sahrens * ,---+--------+------------+---------------------------------. 87fa9e4066Sahrens * | 1 | action | syncpass | txg (lower bits) | 88fa9e4066Sahrens * `---+--------+------------+---------------------------------' 89fa9e4066Sahrens * 63 62 60 59 50 49 0 90fa9e4066Sahrens * 91fa9e4066Sahrens * 92fa9e4066Sahrens * 93fa9e4066Sahrens * non-debug entry 94fa9e4066Sahrens * 95fa9e4066Sahrens * 1 47 1 15 96fa9e4066Sahrens * ,-----------------------------------------------------------. 97fa9e4066Sahrens * | 0 | offset (sm_shift units) | type | run | 98fa9e4066Sahrens * `-----------------------------------------------------------' 99fa9e4066Sahrens * 63 62 17 16 15 0 100fa9e4066Sahrens */ 101fa9e4066Sahrens 102fa9e4066Sahrens /* All this stuff takes and returns bytes */ 103fa9e4066Sahrens #define SM_RUN_DECODE(x) (BF64_DECODE(x, 0, 15) + 1) 104fa9e4066Sahrens #define SM_RUN_ENCODE(x) BF64_ENCODE((x) - 1, 0, 15) 105fa9e4066Sahrens #define SM_TYPE_DECODE(x) BF64_DECODE(x, 15, 1) 106fa9e4066Sahrens #define SM_TYPE_ENCODE(x) BF64_ENCODE(x, 15, 1) 107fa9e4066Sahrens #define SM_OFFSET_DECODE(x) BF64_DECODE(x, 16, 47) 108fa9e4066Sahrens #define SM_OFFSET_ENCODE(x) BF64_ENCODE(x, 16, 47) 109fa9e4066Sahrens #define SM_DEBUG_DECODE(x) BF64_DECODE(x, 63, 1) 110fa9e4066Sahrens #define SM_DEBUG_ENCODE(x) BF64_ENCODE(x, 63, 1) 111fa9e4066Sahrens 112fa9e4066Sahrens #define SM_DEBUG_ACTION_DECODE(x) BF64_DECODE(x, 60, 3) 113fa9e4066Sahrens #define SM_DEBUG_ACTION_ENCODE(x) BF64_ENCODE(x, 60, 3) 114fa9e4066Sahrens 115fa9e4066Sahrens #define SM_DEBUG_SYNCPASS_DECODE(x) BF64_DECODE(x, 50, 10) 116fa9e4066Sahrens #define SM_DEBUG_SYNCPASS_ENCODE(x) BF64_ENCODE(x, 50, 10) 117fa9e4066Sahrens 118fa9e4066Sahrens #define SM_DEBUG_TXG_DECODE(x) BF64_DECODE(x, 0, 50) 119fa9e4066Sahrens #define SM_DEBUG_TXG_ENCODE(x) BF64_ENCODE(x, 0, 50) 120fa9e4066Sahrens 121fa9e4066Sahrens #define SM_RUN_MAX SM_RUN_DECODE(~0ULL) 122fa9e4066Sahrens 123fa9e4066Sahrens #define SM_ALLOC 0x0 124fa9e4066Sahrens #define SM_FREE 0x1 125fa9e4066Sahrens 126fa9e4066Sahrens /* 127fa9e4066Sahrens * The data for a given space map can be kept on blocks of any size. 128fa9e4066Sahrens * Larger blocks entail fewer i/o operations, but they also cause the 129fa9e4066Sahrens * DMU to keep more data in-core, and also to waste more i/o bandwidth 130fa9e4066Sahrens * when only a few blocks have changed since the last transaction group. 131fa9e4066Sahrens * This could use a lot more research, but for now, set the freelist 132fa9e4066Sahrens * block size to 4k (2^12). 133fa9e4066Sahrens */ 134fa9e4066Sahrens #define SPACE_MAP_BLOCKSHIFT 12 135fa9e4066Sahrens 136fa9e4066Sahrens typedef void space_map_func_t(space_map_t *sm, uint64_t start, uint64_t size); 137fa9e4066Sahrens 138fa9e4066Sahrens extern void space_map_create(space_map_t *sm, uint64_t start, uint64_t size, 139ecc2d604Sbonwick uint8_t shift, kmutex_t *lp); 140fa9e4066Sahrens extern void space_map_destroy(space_map_t *sm); 141fa9e4066Sahrens extern void space_map_add(space_map_t *sm, uint64_t start, uint64_t size); 142fa9e4066Sahrens extern void space_map_remove(space_map_t *sm, uint64_t start, uint64_t size); 1438ad4d6ddSJeff Bonwick extern boolean_t space_map_contains(space_map_t *sm, 1448ad4d6ddSJeff Bonwick uint64_t start, uint64_t size); 145fa9e4066Sahrens extern void space_map_vacate(space_map_t *sm, 146fa9e4066Sahrens space_map_func_t *func, space_map_t *mdest); 147ecc2d604Sbonwick extern void space_map_walk(space_map_t *sm, 148fa9e4066Sahrens space_map_func_t *func, space_map_t *mdest); 149fa9e4066Sahrens 150ecc2d604Sbonwick extern void space_map_load_wait(space_map_t *sm); 151ecc2d604Sbonwick extern int space_map_load(space_map_t *sm, space_map_ops_t *ops, 152ecc2d604Sbonwick uint8_t maptype, space_map_obj_t *smo, objset_t *os); 153ecc2d604Sbonwick extern void space_map_unload(space_map_t *sm); 154ecc2d604Sbonwick 155ecc2d604Sbonwick extern uint64_t space_map_alloc(space_map_t *sm, uint64_t size); 156ecc2d604Sbonwick extern void space_map_claim(space_map_t *sm, uint64_t start, uint64_t size); 157ecc2d604Sbonwick extern void space_map_free(space_map_t *sm, uint64_t start, uint64_t size); 158*d6e555bdSGeorge Wilson extern uint64_t space_map_maxsize(space_map_t *sm); 159ecc2d604Sbonwick 160ecc2d604Sbonwick extern void space_map_sync(space_map_t *sm, uint8_t maptype, 161ecc2d604Sbonwick space_map_obj_t *smo, objset_t *os, dmu_tx_t *tx); 162ecc2d604Sbonwick extern void space_map_truncate(space_map_obj_t *smo, 163fa9e4066Sahrens objset_t *os, dmu_tx_t *tx); 164fa9e4066Sahrens 1658ad4d6ddSJeff Bonwick extern void space_map_ref_create(avl_tree_t *t); 1668ad4d6ddSJeff Bonwick extern void space_map_ref_destroy(avl_tree_t *t); 1678ad4d6ddSJeff Bonwick extern void space_map_ref_add_seg(avl_tree_t *t, 1688ad4d6ddSJeff Bonwick uint64_t start, uint64_t end, int64_t refcnt); 1698ad4d6ddSJeff Bonwick extern void space_map_ref_add_map(avl_tree_t *t, 1708ad4d6ddSJeff Bonwick space_map_t *sm, int64_t refcnt); 1718ad4d6ddSJeff Bonwick extern void space_map_ref_generate_map(avl_tree_t *t, 1728ad4d6ddSJeff Bonwick space_map_t *sm, int64_t minref); 1738ad4d6ddSJeff Bonwick 174fa9e4066Sahrens #ifdef __cplusplus 175fa9e4066Sahrens } 176fa9e4066Sahrens #endif 177fa9e4066Sahrens 178fa9e4066Sahrens #endif /* _SYS_SPACE_MAP_H */ 179