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
  }