Print this page
NEX-3165 need some dedup improvements
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
re #12611 rb4105 zpool import panic in ddt_zap_count()
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code

*** 18,27 **** --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. */ #ifndef _SYS_DDT_H #define _SYS_DDT_H
*** 54,63 **** --- 55,75 ---- DDT_CLASS_DUPLICATE, DDT_CLASS_UNIQUE, DDT_CLASSES }; + /* + * Tracks whether a DDE is loading or already loaded and + * which entries got removed from dedup path to support dedup ceiling + */ + enum dde_state { + DDE_LOADING = (1 << 0), + DDE_LOADED = (1 << 1), + DDE_NEW = (1 << 2), + DDE_DONT_SYNC = (1 << 3), + }; + #define DDT_TYPE_CURRENT 0 #define DDT_COMPRESS_BYTEORDER_MASK 0x80 #define DDT_COMPRESS_FUNCTION_MASK 0x7f
*** 109,133 **** */ struct ddt_entry { ddt_key_t dde_key; ddt_phys_t dde_phys[DDT_PHYS_TYPES]; zio_t *dde_lead_zio[DDT_PHYS_TYPES]; struct abd *dde_repair_abd; enum ddt_type dde_type; enum ddt_class dde_class; ! uint8_t dde_loading; ! uint8_t dde_loaded; kcondvar_t dde_cv; avl_node_t dde_node; }; /* * In-core ddt */ struct ddt { ! kmutex_t ddt_lock; ! avl_tree_t ddt_tree; avl_tree_t ddt_repair_tree; enum zio_checksum ddt_checksum; spa_t *ddt_spa; objset_t *ddt_os; uint64_t ddt_stat_object; --- 121,151 ---- */ struct ddt_entry { ddt_key_t dde_key; ddt_phys_t dde_phys[DDT_PHYS_TYPES]; zio_t *dde_lead_zio[DDT_PHYS_TYPES]; + ddt_stat_t dde_lkstat; struct abd *dde_repair_abd; enum ddt_type dde_type; enum ddt_class dde_class; ! uint8_t dde_state; kcondvar_t dde_cv; + kmutex_t dde_lock; avl_node_t dde_node; }; + #define DDT_HASHSZ 0x100 + #define DDT_HASHFN(csum) (*((uint8_t *)&(csum).zc_word[0]) & \ + (DDT_HASHSZ - 1)) + /* * In-core ddt */ struct ddt { ! kmutex_t ddt_lock[DDT_HASHSZ]; ! avl_tree_t ddt_tree[DDT_HASHSZ]; ! kmutex_t ddt_repair_lock; avl_tree_t ddt_repair_tree; enum zio_checksum ddt_checksum; spa_t *ddt_spa; objset_t *ddt_os; uint64_t ddt_stat_object;
*** 163,183 **** dmu_tx_t *tx); int (*ddt_op_remove)(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx); int (*ddt_op_walk)(objset_t *os, uint64_t object, ddt_entry_t *dde, uint64_t *walk); ! uint64_t (*ddt_op_count)(objset_t *os, uint64_t object); } ddt_ops_t; #define DDT_NAMELEN 80 extern void ddt_object_name(ddt_t *ddt, enum ddt_type type, enum ddt_class class, char *name); extern int ddt_object_walk(ddt_t *ddt, enum ddt_type type, enum ddt_class class, uint64_t *walk, ddt_entry_t *dde); ! extern uint64_t ddt_object_count(ddt_t *ddt, enum ddt_type type, ! enum ddt_class class); extern int ddt_object_info(ddt_t *ddt, enum ddt_type type, enum ddt_class class, dmu_object_info_t *); extern boolean_t ddt_object_exists(ddt_t *ddt, enum ddt_type type, enum ddt_class class); --- 181,201 ---- dmu_tx_t *tx); int (*ddt_op_remove)(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx); int (*ddt_op_walk)(objset_t *os, uint64_t object, ddt_entry_t *dde, uint64_t *walk); ! int (*ddt_op_count)(objset_t *os, uint64_t object, uint64_t *count); } ddt_ops_t; #define DDT_NAMELEN 80 extern void ddt_object_name(ddt_t *ddt, enum ddt_type type, enum ddt_class class, char *name); extern int ddt_object_walk(ddt_t *ddt, enum ddt_type type, enum ddt_class class, uint64_t *walk, ddt_entry_t *dde); ! extern int ddt_object_count(ddt_t *ddt, enum ddt_type type, ! enum ddt_class class, uint64_t *count); extern int ddt_object_info(ddt_t *ddt, enum ddt_type type, enum ddt_class class, dmu_object_info_t *); extern boolean_t ddt_object_exists(ddt_t *ddt, enum ddt_type type, enum ddt_class class);
*** 215,226 **** extern size_t ddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len); extern void ddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len); extern ddt_t *ddt_select(spa_t *spa, const blkptr_t *bp); ! extern void ddt_enter(ddt_t *ddt); ! extern void ddt_exit(ddt_t *ddt); extern ddt_entry_t *ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add); extern void ddt_prefetch(spa_t *spa, const blkptr_t *bp); extern void ddt_remove(ddt_t *ddt, ddt_entry_t *dde); extern boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class, --- 233,246 ---- extern size_t ddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len); extern void ddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len); extern ddt_t *ddt_select(spa_t *spa, const blkptr_t *bp); ! extern void ddt_enter(ddt_t *ddt, uint8_t hash); ! extern void ddt_exit(ddt_t *ddt, uint8_t hash); ! extern void dde_enter(ddt_entry_t *dde); ! extern void dde_exit(ddt_entry_t *dde); extern ddt_entry_t *ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add); extern void ddt_prefetch(spa_t *spa, const blkptr_t *bp); extern void ddt_remove(ddt_t *ddt, ddt_entry_t *dde); extern boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class,
*** 236,245 **** --- 256,267 ---- extern void ddt_unload(spa_t *spa); extern void ddt_sync(spa_t *spa, uint64_t txg); extern int ddt_walk(spa_t *spa, ddt_bookmark_t *ddb, ddt_entry_t *dde); extern int ddt_object_update(ddt_t *ddt, enum ddt_type type, enum ddt_class class, ddt_entry_t *dde, dmu_tx_t *tx); + extern void ddt_init(void); + extern void ddt_fini(void); extern const ddt_ops_t ddt_zap_ops; #ifdef __cplusplus }