1*5cabbc6bSPrashanth Sreenivasa /* 2*5cabbc6bSPrashanth Sreenivasa * CDDL HEADER START 3*5cabbc6bSPrashanth Sreenivasa * 4*5cabbc6bSPrashanth Sreenivasa * This file and its contents are supplied under the terms of the 5*5cabbc6bSPrashanth Sreenivasa * Common Development and Distribution License ("CDDL"), version 1.0. 6*5cabbc6bSPrashanth Sreenivasa * You may only use this file in accordance with the terms of version 7*5cabbc6bSPrashanth Sreenivasa * 1.0 of the CDDL. 8*5cabbc6bSPrashanth Sreenivasa * 9*5cabbc6bSPrashanth Sreenivasa * A full copy of the text of the CDDL should have accompanied this 10*5cabbc6bSPrashanth Sreenivasa * source. A copy of the CDDL is also available via the Internet at 11*5cabbc6bSPrashanth Sreenivasa * http://www.illumos.org/license/CDDL. 12*5cabbc6bSPrashanth Sreenivasa * 13*5cabbc6bSPrashanth Sreenivasa * CDDL HEADER END 14*5cabbc6bSPrashanth Sreenivasa */ 15*5cabbc6bSPrashanth Sreenivasa 16*5cabbc6bSPrashanth Sreenivasa /* 17*5cabbc6bSPrashanth Sreenivasa * Copyright (c) 2015 by Delphix. All rights reserved. 18*5cabbc6bSPrashanth Sreenivasa */ 19*5cabbc6bSPrashanth Sreenivasa 20*5cabbc6bSPrashanth Sreenivasa #ifndef _SYS_VDEV_INDIRECT_MAPPING_H 21*5cabbc6bSPrashanth Sreenivasa #define _SYS_VDEV_INDIRECT_MAPPING_H 22*5cabbc6bSPrashanth Sreenivasa 23*5cabbc6bSPrashanth Sreenivasa #include <sys/dmu.h> 24*5cabbc6bSPrashanth Sreenivasa #include <sys/list.h> 25*5cabbc6bSPrashanth Sreenivasa #include <sys/spa.h> 26*5cabbc6bSPrashanth Sreenivasa #include <sys/space_map.h> 27*5cabbc6bSPrashanth Sreenivasa 28*5cabbc6bSPrashanth Sreenivasa #ifdef __cplusplus 29*5cabbc6bSPrashanth Sreenivasa extern "C" { 30*5cabbc6bSPrashanth Sreenivasa #endif 31*5cabbc6bSPrashanth Sreenivasa 32*5cabbc6bSPrashanth Sreenivasa typedef struct vdev_indirect_mapping_entry_phys { 33*5cabbc6bSPrashanth Sreenivasa /* 34*5cabbc6bSPrashanth Sreenivasa * Decode with DVA_MAPPING_* macros. 35*5cabbc6bSPrashanth Sreenivasa * Contains: 36*5cabbc6bSPrashanth Sreenivasa * the source offset (low 63 bits) 37*5cabbc6bSPrashanth Sreenivasa * the one-bit "mark", used for garbage collection (by zdb) 38*5cabbc6bSPrashanth Sreenivasa */ 39*5cabbc6bSPrashanth Sreenivasa uint64_t vimep_src; 40*5cabbc6bSPrashanth Sreenivasa 41*5cabbc6bSPrashanth Sreenivasa /* 42*5cabbc6bSPrashanth Sreenivasa * Note: the DVA's asize is 24 bits, and can thus store ranges 43*5cabbc6bSPrashanth Sreenivasa * up to 8GB. 44*5cabbc6bSPrashanth Sreenivasa */ 45*5cabbc6bSPrashanth Sreenivasa dva_t vimep_dst; 46*5cabbc6bSPrashanth Sreenivasa } vdev_indirect_mapping_entry_phys_t; 47*5cabbc6bSPrashanth Sreenivasa 48*5cabbc6bSPrashanth Sreenivasa #define DVA_MAPPING_GET_SRC_OFFSET(vimep) \ 49*5cabbc6bSPrashanth Sreenivasa BF64_GET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0) 50*5cabbc6bSPrashanth Sreenivasa #define DVA_MAPPING_SET_SRC_OFFSET(vimep, x) \ 51*5cabbc6bSPrashanth Sreenivasa BF64_SET_SB((vimep)->vimep_src, 0, 63, SPA_MINBLOCKSHIFT, 0, x) 52*5cabbc6bSPrashanth Sreenivasa 53*5cabbc6bSPrashanth Sreenivasa typedef struct vdev_indirect_mapping_entry { 54*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_entry_phys_t vime_mapping; 55*5cabbc6bSPrashanth Sreenivasa uint32_t vime_obsolete_count; 56*5cabbc6bSPrashanth Sreenivasa list_node_t vime_node; 57*5cabbc6bSPrashanth Sreenivasa } vdev_indirect_mapping_entry_t; 58*5cabbc6bSPrashanth Sreenivasa 59*5cabbc6bSPrashanth Sreenivasa /* 60*5cabbc6bSPrashanth Sreenivasa * This is stored in the bonus buffer of the mapping object, see comment of 61*5cabbc6bSPrashanth Sreenivasa * vdev_indirect_config for more details. 62*5cabbc6bSPrashanth Sreenivasa */ 63*5cabbc6bSPrashanth Sreenivasa typedef struct vdev_indirect_mapping_phys { 64*5cabbc6bSPrashanth Sreenivasa uint64_t vimp_max_offset; 65*5cabbc6bSPrashanth Sreenivasa uint64_t vimp_bytes_mapped; 66*5cabbc6bSPrashanth Sreenivasa uint64_t vimp_num_entries; /* number of v_i_m_entry_phys_t's */ 67*5cabbc6bSPrashanth Sreenivasa 68*5cabbc6bSPrashanth Sreenivasa /* 69*5cabbc6bSPrashanth Sreenivasa * For each entry in the mapping object, this object contains an 70*5cabbc6bSPrashanth Sreenivasa * entry representing the number of bytes of that mapping entry 71*5cabbc6bSPrashanth Sreenivasa * that were no longer in use by the pool at the time this indirect 72*5cabbc6bSPrashanth Sreenivasa * vdev was last condensed. 73*5cabbc6bSPrashanth Sreenivasa */ 74*5cabbc6bSPrashanth Sreenivasa uint64_t vimp_counts_object; 75*5cabbc6bSPrashanth Sreenivasa } vdev_indirect_mapping_phys_t; 76*5cabbc6bSPrashanth Sreenivasa 77*5cabbc6bSPrashanth Sreenivasa #define VDEV_INDIRECT_MAPPING_SIZE_V0 (3 * sizeof (uint64_t)) 78*5cabbc6bSPrashanth Sreenivasa 79*5cabbc6bSPrashanth Sreenivasa typedef struct vdev_indirect_mapping { 80*5cabbc6bSPrashanth Sreenivasa uint64_t vim_object; 81*5cabbc6bSPrashanth Sreenivasa boolean_t vim_havecounts; 82*5cabbc6bSPrashanth Sreenivasa 83*5cabbc6bSPrashanth Sreenivasa /* 84*5cabbc6bSPrashanth Sreenivasa * An ordered array of all mapping entries, sorted by source offset. 85*5cabbc6bSPrashanth Sreenivasa * Note that vim_entries is needed during a removal (and contains 86*5cabbc6bSPrashanth Sreenivasa * mappings that have been synced to disk so far) to handle frees 87*5cabbc6bSPrashanth Sreenivasa * from the removing device. 88*5cabbc6bSPrashanth Sreenivasa */ 89*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_entry_phys_t *vim_entries; 90*5cabbc6bSPrashanth Sreenivasa 91*5cabbc6bSPrashanth Sreenivasa objset_t *vim_objset; 92*5cabbc6bSPrashanth Sreenivasa 93*5cabbc6bSPrashanth Sreenivasa dmu_buf_t *vim_dbuf; 94*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_phys_t *vim_phys; 95*5cabbc6bSPrashanth Sreenivasa } vdev_indirect_mapping_t; 96*5cabbc6bSPrashanth Sreenivasa 97*5cabbc6bSPrashanth Sreenivasa extern vdev_indirect_mapping_t *vdev_indirect_mapping_open(objset_t *os, 98*5cabbc6bSPrashanth Sreenivasa uint64_t object); 99*5cabbc6bSPrashanth Sreenivasa extern void vdev_indirect_mapping_close(vdev_indirect_mapping_t *vim); 100*5cabbc6bSPrashanth Sreenivasa extern uint64_t vdev_indirect_mapping_alloc(objset_t *os, dmu_tx_t *tx); 101*5cabbc6bSPrashanth Sreenivasa extern void vdev_indirect_mapping_free(objset_t *os, uint64_t obj, 102*5cabbc6bSPrashanth Sreenivasa dmu_tx_t *tx); 103*5cabbc6bSPrashanth Sreenivasa 104*5cabbc6bSPrashanth Sreenivasa extern uint64_t vdev_indirect_mapping_num_entries(vdev_indirect_mapping_t *vim); 105*5cabbc6bSPrashanth Sreenivasa extern uint64_t vdev_indirect_mapping_max_offset(vdev_indirect_mapping_t *vim); 106*5cabbc6bSPrashanth Sreenivasa extern uint64_t vdev_indirect_mapping_object(vdev_indirect_mapping_t *vim); 107*5cabbc6bSPrashanth Sreenivasa extern uint64_t vdev_indirect_mapping_bytes_mapped( 108*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_t *vim); 109*5cabbc6bSPrashanth Sreenivasa extern uint64_t vdev_indirect_mapping_size(vdev_indirect_mapping_t *vim); 110*5cabbc6bSPrashanth Sreenivasa 111*5cabbc6bSPrashanth Sreenivasa /* 112*5cabbc6bSPrashanth Sreenivasa * Writes the given list of vdev_indirect_mapping_entry_t to the mapping 113*5cabbc6bSPrashanth Sreenivasa * then updates internal state. 114*5cabbc6bSPrashanth Sreenivasa */ 115*5cabbc6bSPrashanth Sreenivasa extern void vdev_indirect_mapping_add_entries(vdev_indirect_mapping_t *vim, 116*5cabbc6bSPrashanth Sreenivasa list_t *vime_list, dmu_tx_t *tx); 117*5cabbc6bSPrashanth Sreenivasa 118*5cabbc6bSPrashanth Sreenivasa extern vdev_indirect_mapping_entry_phys_t * 119*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_entry_for_offset(vdev_indirect_mapping_t *vim, 120*5cabbc6bSPrashanth Sreenivasa uint64_t offset); 121*5cabbc6bSPrashanth Sreenivasa 122*5cabbc6bSPrashanth Sreenivasa extern vdev_indirect_mapping_entry_phys_t * 123*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_entry_for_offset_or_next(vdev_indirect_mapping_t *vim, 124*5cabbc6bSPrashanth Sreenivasa uint64_t offset); 125*5cabbc6bSPrashanth Sreenivasa 126*5cabbc6bSPrashanth Sreenivasa extern uint32_t *vdev_indirect_mapping_load_obsolete_counts( 127*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_t *vim); 128*5cabbc6bSPrashanth Sreenivasa extern void vdev_indirect_mapping_load_obsolete_spacemap( 129*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_t *vim, 130*5cabbc6bSPrashanth Sreenivasa uint32_t *counts, space_map_t *obsolete_space_sm); 131*5cabbc6bSPrashanth Sreenivasa extern void vdev_indirect_mapping_increment_obsolete_count( 132*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_t *vim, 133*5cabbc6bSPrashanth Sreenivasa uint64_t offset, uint64_t asize, uint32_t *counts); 134*5cabbc6bSPrashanth Sreenivasa extern void vdev_indirect_mapping_free_obsolete_counts( 135*5cabbc6bSPrashanth Sreenivasa vdev_indirect_mapping_t *vim, uint32_t *counts); 136*5cabbc6bSPrashanth Sreenivasa 137*5cabbc6bSPrashanth Sreenivasa #ifdef __cplusplus 138*5cabbc6bSPrashanth Sreenivasa } 139*5cabbc6bSPrashanth Sreenivasa #endif 140*5cabbc6bSPrashanth Sreenivasa 141*5cabbc6bSPrashanth Sreenivasa #endif /* _SYS_VDEV_INDIRECT_MAPPING_H */ 142