1 1.1 haad /* 2 1.1 haad * CDDL HEADER START 3 1.1 haad * 4 1.1 haad * The contents of this file are subject to the terms of the 5 1.1 haad * Common Development and Distribution License (the "License"). 6 1.1 haad * You may not use this file except in compliance with the License. 7 1.1 haad * 8 1.1 haad * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1.1 haad * or http://www.opensolaris.org/os/licensing. 10 1.1 haad * See the License for the specific language governing permissions 11 1.1 haad * and limitations under the License. 12 1.1 haad * 13 1.1 haad * When distributing Covered Code, include this CDDL HEADER in each 14 1.1 haad * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1.1 haad * If applicable, add the following below this CDDL HEADER, with the 16 1.1 haad * fields enclosed by brackets "[]" replaced with your own identifying 17 1.1 haad * information: Portions Copyright [yyyy] [name of copyright owner] 18 1.1 haad * 19 1.1 haad * CDDL HEADER END 20 1.1 haad */ 21 1.1 haad /* 22 1.3 chs * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 23 1.1 haad */ 24 1.1 haad 25 1.1 haad #ifndef _SYS_DDT_H 26 1.1 haad #define _SYS_DDT_H 27 1.1 haad 28 1.1 haad #include <sys/sysmacros.h> 29 1.1 haad #include <sys/types.h> 30 1.1 haad #include <sys/fs/zfs.h> 31 1.1 haad #include <sys/zio.h> 32 1.1 haad #include <sys/dmu.h> 33 1.1 haad 34 1.1 haad #ifdef __cplusplus 35 1.1 haad extern "C" { 36 1.1 haad #endif 37 1.1 haad 38 1.1 haad /* 39 1.1 haad * On-disk DDT formats, in the desired search order (newest version first). 40 1.1 haad */ 41 1.1 haad enum ddt_type { 42 1.1 haad DDT_TYPE_ZAP = 0, 43 1.1 haad DDT_TYPES 44 1.1 haad }; 45 1.1 haad 46 1.1 haad /* 47 1.1 haad * DDT classes, in the desired search order (highest replication level first). 48 1.1 haad */ 49 1.1 haad enum ddt_class { 50 1.1 haad DDT_CLASS_DITTO = 0, 51 1.1 haad DDT_CLASS_DUPLICATE, 52 1.1 haad DDT_CLASS_UNIQUE, 53 1.1 haad DDT_CLASSES 54 1.1 haad }; 55 1.1 haad 56 1.1 haad #define DDT_TYPE_CURRENT 0 57 1.1 haad 58 1.1 haad #define DDT_COMPRESS_BYTEORDER_MASK 0x80 59 1.1 haad #define DDT_COMPRESS_FUNCTION_MASK 0x7f 60 1.1 haad 61 1.1 haad /* 62 1.1 haad * On-disk ddt entry: key (name) and physical storage (value). 63 1.1 haad */ 64 1.1 haad typedef struct ddt_key { 65 1.1 haad zio_cksum_t ddk_cksum; /* 256-bit block checksum */ 66 1.3 chs /* 67 1.3 chs * Encoded with logical & physical size, and compression, as follows: 68 1.3 chs * +-------+-------+-------+-------+-------+-------+-------+-------+ 69 1.3 chs * | 0 | 0 | 0 | comp | PSIZE | LSIZE | 70 1.3 chs * +-------+-------+-------+-------+-------+-------+-------+-------+ 71 1.3 chs */ 72 1.3 chs uint64_t ddk_prop; 73 1.1 haad } ddt_key_t; 74 1.1 haad 75 1.1 haad #define DDK_GET_LSIZE(ddk) \ 76 1.1 haad BF64_GET_SB((ddk)->ddk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1) 77 1.1 haad #define DDK_SET_LSIZE(ddk, x) \ 78 1.1 haad BF64_SET_SB((ddk)->ddk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x) 79 1.1 haad 80 1.1 haad #define DDK_GET_PSIZE(ddk) \ 81 1.1 haad BF64_GET_SB((ddk)->ddk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1) 82 1.1 haad #define DDK_SET_PSIZE(ddk, x) \ 83 1.1 haad BF64_SET_SB((ddk)->ddk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x) 84 1.1 haad 85 1.1 haad #define DDK_GET_COMPRESS(ddk) BF64_GET((ddk)->ddk_prop, 32, 8) 86 1.1 haad #define DDK_SET_COMPRESS(ddk, x) BF64_SET((ddk)->ddk_prop, 32, 8, x) 87 1.1 haad 88 1.1 haad #define DDT_KEY_WORDS (sizeof (ddt_key_t) / sizeof (uint64_t)) 89 1.1 haad 90 1.1 haad typedef struct ddt_phys { 91 1.1 haad dva_t ddp_dva[SPA_DVAS_PER_BP]; 92 1.1 haad uint64_t ddp_refcnt; 93 1.1 haad uint64_t ddp_phys_birth; 94 1.1 haad } ddt_phys_t; 95 1.1 haad 96 1.1 haad enum ddt_phys_type { 97 1.1 haad DDT_PHYS_DITTO = 0, 98 1.1 haad DDT_PHYS_SINGLE = 1, 99 1.1 haad DDT_PHYS_DOUBLE = 2, 100 1.1 haad DDT_PHYS_TRIPLE = 3, 101 1.1 haad DDT_PHYS_TYPES 102 1.3 chs }; 103 1.1 haad 104 1.1 haad /* 105 1.1 haad * In-core ddt entry 106 1.1 haad */ 107 1.1 haad struct ddt_entry { 108 1.1 haad ddt_key_t dde_key; 109 1.1 haad ddt_phys_t dde_phys[DDT_PHYS_TYPES]; 110 1.1 haad zio_t *dde_lead_zio[DDT_PHYS_TYPES]; 111 1.1 haad void *dde_repair_data; 112 1.1 haad enum ddt_type dde_type; 113 1.1 haad enum ddt_class dde_class; 114 1.1 haad uint8_t dde_loading; 115 1.1 haad uint8_t dde_loaded; 116 1.1 haad kcondvar_t dde_cv; 117 1.1 haad avl_node_t dde_node; 118 1.1 haad }; 119 1.1 haad 120 1.1 haad /* 121 1.1 haad * In-core ddt 122 1.1 haad */ 123 1.1 haad struct ddt { 124 1.1 haad kmutex_t ddt_lock; 125 1.1 haad avl_tree_t ddt_tree; 126 1.1 haad avl_tree_t ddt_repair_tree; 127 1.1 haad enum zio_checksum ddt_checksum; 128 1.1 haad spa_t *ddt_spa; 129 1.1 haad objset_t *ddt_os; 130 1.1 haad uint64_t ddt_stat_object; 131 1.1 haad uint64_t ddt_object[DDT_TYPES][DDT_CLASSES]; 132 1.1 haad ddt_histogram_t ddt_histogram[DDT_TYPES][DDT_CLASSES]; 133 1.3 chs ddt_histogram_t ddt_histogram_cache[DDT_TYPES][DDT_CLASSES]; 134 1.3 chs ddt_object_t ddt_object_stats[DDT_TYPES][DDT_CLASSES]; 135 1.1 haad avl_node_t ddt_node; 136 1.1 haad }; 137 1.1 haad 138 1.1 haad /* 139 1.1 haad * In-core and on-disk bookmark for DDT walks 140 1.1 haad */ 141 1.1 haad typedef struct ddt_bookmark { 142 1.1 haad uint64_t ddb_class; 143 1.1 haad uint64_t ddb_type; 144 1.1 haad uint64_t ddb_checksum; 145 1.1 haad uint64_t ddb_cursor; 146 1.1 haad } ddt_bookmark_t; 147 1.1 haad 148 1.1 haad /* 149 1.1 haad * Ops vector to access a specific DDT object type. 150 1.1 haad */ 151 1.1 haad typedef struct ddt_ops { 152 1.1 haad char ddt_op_name[32]; 153 1.1 haad int (*ddt_op_create)(objset_t *os, uint64_t *object, dmu_tx_t *tx, 154 1.1 haad boolean_t prehash); 155 1.1 haad int (*ddt_op_destroy)(objset_t *os, uint64_t object, dmu_tx_t *tx); 156 1.1 haad int (*ddt_op_lookup)(objset_t *os, uint64_t object, ddt_entry_t *dde); 157 1.3 chs void (*ddt_op_prefetch)(objset_t *os, uint64_t object, 158 1.3 chs ddt_entry_t *dde); 159 1.1 haad int (*ddt_op_update)(objset_t *os, uint64_t object, ddt_entry_t *dde, 160 1.1 haad dmu_tx_t *tx); 161 1.1 haad int (*ddt_op_remove)(objset_t *os, uint64_t object, ddt_entry_t *dde, 162 1.1 haad dmu_tx_t *tx); 163 1.1 haad int (*ddt_op_walk)(objset_t *os, uint64_t object, ddt_entry_t *dde, 164 1.1 haad uint64_t *walk); 165 1.3 chs int (*ddt_op_count)(objset_t *os, uint64_t object, uint64_t *count); 166 1.1 haad } ddt_ops_t; 167 1.1 haad 168 1.1 haad #define DDT_NAMELEN 80 169 1.1 haad 170 1.1 haad extern void ddt_object_name(ddt_t *ddt, enum ddt_type type, 171 1.3 chs enum ddt_class cls, char *name); 172 1.1 haad extern int ddt_object_walk(ddt_t *ddt, enum ddt_type type, 173 1.3 chs enum ddt_class cls, uint64_t *walk, ddt_entry_t *dde); 174 1.3 chs extern int ddt_object_count(ddt_t *ddt, enum ddt_type type, 175 1.3 chs enum ddt_class cls, uint64_t *count); 176 1.1 haad extern int ddt_object_info(ddt_t *ddt, enum ddt_type type, 177 1.3 chs enum ddt_class cls, dmu_object_info_t *); 178 1.1 haad extern boolean_t ddt_object_exists(ddt_t *ddt, enum ddt_type type, 179 1.3 chs enum ddt_class cls); 180 1.1 haad 181 1.1 haad extern void ddt_bp_fill(const ddt_phys_t *ddp, blkptr_t *bp, 182 1.1 haad uint64_t txg); 183 1.1 haad extern void ddt_bp_create(enum zio_checksum checksum, const ddt_key_t *ddk, 184 1.1 haad const ddt_phys_t *ddp, blkptr_t *bp); 185 1.1 haad 186 1.1 haad extern void ddt_key_fill(ddt_key_t *ddk, const blkptr_t *bp); 187 1.1 haad 188 1.1 haad extern void ddt_phys_fill(ddt_phys_t *ddp, const blkptr_t *bp); 189 1.1 haad extern void ddt_phys_clear(ddt_phys_t *ddp); 190 1.1 haad extern void ddt_phys_addref(ddt_phys_t *ddp); 191 1.1 haad extern void ddt_phys_decref(ddt_phys_t *ddp); 192 1.1 haad extern void ddt_phys_free(ddt_t *ddt, ddt_key_t *ddk, ddt_phys_t *ddp, 193 1.1 haad uint64_t txg); 194 1.1 haad extern ddt_phys_t *ddt_phys_select(const ddt_entry_t *dde, const blkptr_t *bp); 195 1.1 haad extern uint64_t ddt_phys_total_refcnt(const ddt_entry_t *dde); 196 1.1 haad 197 1.1 haad extern void ddt_stat_add(ddt_stat_t *dst, const ddt_stat_t *src, uint64_t neg); 198 1.1 haad 199 1.1 haad extern void ddt_histogram_add(ddt_histogram_t *dst, const ddt_histogram_t *src); 200 1.1 haad extern void ddt_histogram_stat(ddt_stat_t *dds, const ddt_histogram_t *ddh); 201 1.1 haad extern boolean_t ddt_histogram_empty(const ddt_histogram_t *ddh); 202 1.1 haad extern void ddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo); 203 1.1 haad extern void ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh); 204 1.1 haad extern void ddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total); 205 1.1 haad 206 1.1 haad extern uint64_t ddt_get_dedup_dspace(spa_t *spa); 207 1.1 haad extern uint64_t ddt_get_pool_dedup_ratio(spa_t *spa); 208 1.1 haad 209 1.1 haad extern int ddt_ditto_copies_needed(ddt_t *ddt, ddt_entry_t *dde, 210 1.1 haad ddt_phys_t *ddp_willref); 211 1.1 haad extern int ddt_ditto_copies_present(ddt_entry_t *dde); 212 1.1 haad 213 1.1 haad extern size_t ddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len); 214 1.1 haad extern void ddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len); 215 1.1 haad 216 1.1 haad extern ddt_t *ddt_select(spa_t *spa, const blkptr_t *bp); 217 1.1 haad extern void ddt_enter(ddt_t *ddt); 218 1.1 haad extern void ddt_exit(ddt_t *ddt); 219 1.1 haad extern ddt_entry_t *ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add); 220 1.3 chs extern void ddt_prefetch(spa_t *spa, const blkptr_t *bp); 221 1.1 haad extern void ddt_remove(ddt_t *ddt, ddt_entry_t *dde); 222 1.1 haad 223 1.1 haad extern boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class, 224 1.1 haad const blkptr_t *bp); 225 1.1 haad 226 1.1 haad extern ddt_entry_t *ddt_repair_start(ddt_t *ddt, const blkptr_t *bp); 227 1.1 haad extern void ddt_repair_done(ddt_t *ddt, ddt_entry_t *dde); 228 1.1 haad 229 1.1 haad extern int ddt_entry_compare(const void *x1, const void *x2); 230 1.1 haad 231 1.1 haad extern void ddt_create(spa_t *spa); 232 1.1 haad extern int ddt_load(spa_t *spa); 233 1.1 haad extern void ddt_unload(spa_t *spa); 234 1.1 haad extern void ddt_sync(spa_t *spa, uint64_t txg); 235 1.1 haad extern int ddt_walk(spa_t *spa, ddt_bookmark_t *ddb, ddt_entry_t *dde); 236 1.3 chs extern int ddt_object_update(ddt_t *ddt, enum ddt_type type, 237 1.3 chs enum ddt_class cls, ddt_entry_t *dde, dmu_tx_t *tx); 238 1.1 haad 239 1.1 haad extern const ddt_ops_t ddt_zap_ops; 240 1.1 haad 241 1.1 haad #ifdef __cplusplus 242 1.1 haad } 243 1.1 haad #endif 244 1.1 haad 245 1.1 haad #endif /* _SYS_DDT_H */ 246