FreeBSD ZFS
The Zettabyte File System

sys/ddt.h

Go to the documentation of this file.
00001 /*
00002  * CDDL HEADER START
00003  *
00004  * The contents of this file are subject to the terms of the
00005  * Common Development and Distribution License (the "License").
00006  * You may not use this file except in compliance with the License.
00007  *
00008  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
00009  * or http://www.opensolaris.org/os/licensing.
00010  * See the License for the specific language governing permissions
00011  * and limitations under the License.
00012  *
00013  * When distributing Covered Code, include this CDDL HEADER in each
00014  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
00015  * If applicable, add the following below this CDDL HEADER, with the
00016  * fields enclosed by brackets "[]" replaced with your own identifying
00017  * information: Portions Copyright [yyyy] [name of copyright owner]
00018  *
00019  * CDDL HEADER END
00020  */
00021 /*
00022  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
00023  */
00024 
00025 #ifndef _SYS_DDT_H
00026 #define _SYS_DDT_H
00027 
00028 #include <sys/sysmacros.h>
00029 #include <sys/types.h>
00030 #include <sys/fs/zfs.h>
00031 #include <sys/zio.h>
00032 #include <sys/dmu.h>
00033 
00034 #ifdef  __cplusplus
00035 extern "C" {
00036 #endif
00037 
00041 enum ddt_type {
00042         DDT_TYPE_ZAP = 0,
00043         DDT_TYPES
00044 };
00045 
00049 enum ddt_class {
00050         DDT_CLASS_DITTO = 0,
00051         DDT_CLASS_DUPLICATE,
00052         DDT_CLASS_UNIQUE,
00053         DDT_CLASSES
00054 };
00055 
00056 #define DDT_TYPE_CURRENT                0
00057 
00058 #define DDT_COMPRESS_BYTEORDER_MASK     0x80
00059 #define DDT_COMPRESS_FUNCTION_MASK      0x7f
00060 
00064 typedef struct ddt_key {
00065         zio_cksum_t     ddk_cksum;      
00076         uint64_t        ddk_prop;       
00077 } ddt_key_t;
00078 
00079 #define DDK_GET_LSIZE(ddk)      \
00080         BF64_GET_SB((ddk)->ddk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1)
00081 #define DDK_SET_LSIZE(ddk, x)   \
00082         BF64_SET_SB((ddk)->ddk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x)
00083 
00084 #define DDK_GET_PSIZE(ddk)      \
00085         BF64_GET_SB((ddk)->ddk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1)
00086 #define DDK_SET_PSIZE(ddk, x)   \
00087         BF64_SET_SB((ddk)->ddk_prop, 16, 16, SPA_MINBLOCKSHIFT, 1, x)
00088 
00089 #define DDK_GET_COMPRESS(ddk)           BF64_GET((ddk)->ddk_prop, 32, 8)
00090 #define DDK_SET_COMPRESS(ddk, x)        BF64_SET((ddk)->ddk_prop, 32, 8, x)
00091 
00092 #define DDT_KEY_WORDS   (sizeof (ddt_key_t) / sizeof (uint64_t))
00093 
00094 typedef struct ddt_phys {
00095         dva_t           ddp_dva[SPA_DVAS_PER_BP];
00096         uint64_t        ddp_refcnt;
00097         uint64_t        ddp_phys_birth;
00098 } ddt_phys_t;
00099 
00100 enum ddt_phys_type {
00101         DDT_PHYS_DITTO = 0,
00102         DDT_PHYS_SINGLE = 1,
00103         DDT_PHYS_DOUBLE = 2,
00104         DDT_PHYS_TRIPLE = 3,
00105         DDT_PHYS_TYPES
00106 };
00107 
00111 struct ddt_entry {
00112         ddt_key_t       dde_key;
00113         ddt_phys_t      dde_phys[DDT_PHYS_TYPES];
00114         zio_t           *dde_lead_zio[DDT_PHYS_TYPES];
00115         void            *dde_repair_data;
00116         enum ddt_type   dde_type;
00117         enum ddt_class  dde_class;
00118         uint8_t         dde_loading;
00119         uint8_t         dde_loaded;
00120         kcondvar_t      dde_cv;
00121         avl_node_t      dde_node;
00122 };
00123 
00127 struct ddt {
00128         kmutex_t        ddt_lock;
00129         avl_tree_t      ddt_tree;
00130         avl_tree_t      ddt_repair_tree;
00131         enum zio_checksum ddt_checksum;
00132         spa_t           *ddt_spa;
00133         objset_t        *ddt_os;
00134         uint64_t        ddt_stat_object;
00135         uint64_t        ddt_object[DDT_TYPES][DDT_CLASSES];
00136         ddt_histogram_t ddt_histogram[DDT_TYPES][DDT_CLASSES];
00137         ddt_histogram_t ddt_histogram_cache[DDT_TYPES][DDT_CLASSES];
00138         ddt_object_t    ddt_object_stats[DDT_TYPES][DDT_CLASSES];
00139         avl_node_t      ddt_node;
00140 };
00141 
00145 typedef struct ddt_bookmark {
00146         uint64_t        ddb_class;
00147         uint64_t        ddb_type;
00148         uint64_t        ddb_checksum;
00149         uint64_t        ddb_cursor;
00150 } ddt_bookmark_t;
00151 
00155 typedef struct ddt_ops {
00156         char ddt_op_name[32];
00157         int (*ddt_op_create)(objset_t *os, uint64_t *object, dmu_tx_t *tx,
00158             boolean_t prehash);
00159         int (*ddt_op_destroy)(objset_t *os, uint64_t object, dmu_tx_t *tx);
00160         int (*ddt_op_lookup)(objset_t *os, uint64_t object, ddt_entry_t *dde);
00161         void (*ddt_op_prefetch)(objset_t *os, uint64_t object,
00162             ddt_entry_t *dde);
00163         int (*ddt_op_update)(objset_t *os, uint64_t object, ddt_entry_t *dde,
00164             dmu_tx_t *tx);
00165         int (*ddt_op_remove)(objset_t *os, uint64_t object, ddt_entry_t *dde,
00166             dmu_tx_t *tx);
00167         int (*ddt_op_walk)(objset_t *os, uint64_t object, ddt_entry_t *dde,
00168             uint64_t *walk);
00169         uint64_t (*ddt_op_count)(objset_t *os, uint64_t object);
00170 } ddt_ops_t;
00171 
00172 #define DDT_NAMELEN     80
00173 
00174 extern void ddt_object_name(ddt_t *ddt, enum ddt_type type,
00175     enum ddt_class cls, char *name);
00176 extern int ddt_object_walk(ddt_t *ddt, enum ddt_type type,
00177     enum ddt_class cls, uint64_t *walk, ddt_entry_t *dde);
00178 extern uint64_t ddt_object_count(ddt_t *ddt, enum ddt_type type,
00179     enum ddt_class cls);
00180 extern int ddt_object_info(ddt_t *ddt, enum ddt_type type,
00181     enum ddt_class cls, dmu_object_info_t *);
00182 extern boolean_t ddt_object_exists(ddt_t *ddt, enum ddt_type type,
00183     enum ddt_class cls);
00184 
00185 extern void ddt_bp_fill(const ddt_phys_t *ddp, blkptr_t *bp,
00186     uint64_t txg);
00187 extern void ddt_bp_create(enum zio_checksum checksum, const ddt_key_t *ddk,
00188     const ddt_phys_t *ddp, blkptr_t *bp);
00189 
00190 extern void ddt_key_fill(ddt_key_t *ddk, const blkptr_t *bp);
00191 
00192 extern void ddt_phys_fill(ddt_phys_t *ddp, const blkptr_t *bp);
00193 extern void ddt_phys_clear(ddt_phys_t *ddp);
00194 extern void ddt_phys_addref(ddt_phys_t *ddp);
00195 extern void ddt_phys_decref(ddt_phys_t *ddp);
00196 extern void ddt_phys_free(ddt_t *ddt, ddt_key_t *ddk, ddt_phys_t *ddp,
00197     uint64_t txg);
00198 extern ddt_phys_t *ddt_phys_select(const ddt_entry_t *dde, const blkptr_t *bp);
00199 extern uint64_t ddt_phys_total_refcnt(const ddt_entry_t *dde);
00200 
00201 extern void ddt_stat_add(ddt_stat_t *dst, const ddt_stat_t *src, uint64_t neg);
00202 
00203 extern void ddt_histogram_add(ddt_histogram_t *dst, const ddt_histogram_t *src);
00204 extern void ddt_histogram_stat(ddt_stat_t *dds, const ddt_histogram_t *ddh);
00205 extern boolean_t ddt_histogram_empty(const ddt_histogram_t *ddh);
00206 extern void ddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo);
00207 extern void ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh);
00208 extern void ddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total);
00209 
00210 extern uint64_t ddt_get_dedup_dspace(spa_t *spa);
00211 extern uint64_t ddt_get_pool_dedup_ratio(spa_t *spa);
00212 
00213 extern int ddt_ditto_copies_needed(ddt_t *ddt, ddt_entry_t *dde,
00214     ddt_phys_t *ddp_willref);
00215 extern int ddt_ditto_copies_present(ddt_entry_t *dde);
00216 
00217 extern size_t ddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len);
00218 extern void ddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len);
00219 
00220 extern ddt_t *ddt_select(spa_t *spa, const blkptr_t *bp);
00221 extern void ddt_enter(ddt_t *ddt);
00222 extern void ddt_exit(ddt_t *ddt);
00223 extern ddt_entry_t *ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add);
00224 extern void ddt_prefetch(spa_t *spa, const blkptr_t *bp);
00225 extern void ddt_remove(ddt_t *ddt, ddt_entry_t *dde);
00226 
00227 extern boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class,
00228     const blkptr_t *bp);
00229 
00230 extern ddt_entry_t *ddt_repair_start(ddt_t *ddt, const blkptr_t *bp);
00231 extern void ddt_repair_done(ddt_t *ddt, ddt_entry_t *dde);
00232 
00233 extern int ddt_entry_compare(const void *x1, const void *x2);
00234 
00235 extern void ddt_create(spa_t *spa);
00236 extern int ddt_load(spa_t *spa);
00237 extern void ddt_unload(spa_t *spa);
00238 extern void ddt_sync(spa_t *spa, uint64_t txg);
00239 extern int ddt_walk(spa_t *spa, ddt_bookmark_t *ddb, ddt_entry_t *dde);
00240 extern int ddt_object_update(ddt_t *ddt, enum ddt_type type,
00241     enum ddt_class cls, ddt_entry_t *dde, dmu_tx_t *tx);
00242 
00243 extern const ddt_ops_t ddt_zap_ops;
00244 
00245 #ifdef  __cplusplus
00246 }
00247 #endif
00248 
00249 #endif  /* _SYS_DDT_H */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines