mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
ddt: dedup table quota enforcement
This adds two new pool properties: - dedup_table_size, the total size of all DDTs on the pool; and - dedup_table_quota, the maximum possible size of all DDTs in the pool When set, quota will be enforced by checking when a new entry is about to be created. If the pool is over its dedup quota, the entry won't be created, and the corresponding write will be converted to a regular non-dedup write. Note that existing entries can be updated (ie their refcounts changed), as that reuses the space rather than requiring more. dedup_table_quota can be set to 'auto', which will set it based on the size of the devices backing the "dedup" allocation device. This makes it possible to limit the DDTs to the size of a dedup vdev only, such that when the device fills, no new blocks are deduplicated. Sponsored-by: iXsystems, Inc. Sponsored-By: Klara Inc. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Signed-off-by: Don Brady <don.brady@klarasystems.com> Co-authored-by: Don Brady <don.brady@klarasystems.com> Co-authored-by: Rob Wing <rob.wing@klarasystems.com> Co-authored-by: Sean Eric Fagan <sean.fagan@klarasystems.com> Closes #15889
This commit is contained in:
+4
-1
@@ -151,7 +151,8 @@ enum ddt_phys_type {
|
||||
*/
|
||||
|
||||
/* State flags for dde_flags */
|
||||
#define DDE_FLAG_LOADED (1 << 0) /* entry ready for use */
|
||||
#define DDE_FLAG_LOADED (1 << 0) /* entry ready for use */
|
||||
#define DDE_FLAG_OVERQUOTA (1 << 1) /* entry unusable, no space */
|
||||
|
||||
typedef struct {
|
||||
/* key must be first for ddt_key_compare */
|
||||
@@ -170,6 +171,7 @@ typedef struct {
|
||||
|
||||
uint8_t dde_flags; /* load state flags */
|
||||
kcondvar_t dde_cv; /* signaled when load completes */
|
||||
uint64_t dde_waiters; /* count of waiters on dde_cv */
|
||||
|
||||
avl_node_t dde_node; /* ddt_tree node */
|
||||
} ddt_entry_t;
|
||||
@@ -228,6 +230,7 @@ extern void ddt_histogram_add(ddt_histogram_t *dst, const ddt_histogram_t *src);
|
||||
extern void ddt_histogram_stat(ddt_stat_t *dds, const ddt_histogram_t *ddh);
|
||||
extern boolean_t ddt_histogram_empty(const ddt_histogram_t *ddh);
|
||||
extern void ddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo);
|
||||
extern uint64_t ddt_get_ddt_dsize(spa_t *spa);
|
||||
extern void ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh);
|
||||
extern void ddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total);
|
||||
|
||||
|
||||
@@ -258,6 +258,8 @@ typedef enum {
|
||||
ZPOOL_PROP_BCLONEUSED,
|
||||
ZPOOL_PROP_BCLONESAVED,
|
||||
ZPOOL_PROP_BCLONERATIO,
|
||||
ZPOOL_PROP_DEDUP_TABLE_SIZE,
|
||||
ZPOOL_PROP_DEDUP_TABLE_QUOTA,
|
||||
ZPOOL_NUM_PROPS
|
||||
} zpool_prop_t;
|
||||
|
||||
|
||||
@@ -1051,6 +1051,7 @@ extern metaslab_class_t *spa_special_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_dedup_class(spa_t *spa);
|
||||
extern metaslab_class_t *spa_preferred_class(spa_t *spa, uint64_t size,
|
||||
dmu_object_type_t objtype, uint_t level, uint_t special_smallblk);
|
||||
extern boolean_t spa_special_has_ddt(spa_t *spa);
|
||||
|
||||
extern void spa_evicting_os_register(spa_t *, objset_t *os);
|
||||
extern void spa_evicting_os_deregister(spa_t *, objset_t *os);
|
||||
|
||||
@@ -465,6 +465,9 @@ struct spa {
|
||||
boolean_t spa_waiters_cancel; /* waiters should return */
|
||||
|
||||
char *spa_compatibility; /* compatibility file(s) */
|
||||
uint64_t spa_dedup_table_quota; /* property DDT maximum size */
|
||||
uint64_t spa_dedup_dsize; /* cached on-disk size of DDT */
|
||||
uint64_t spa_dedup_class_full_txg; /* txg dedup class was full */
|
||||
|
||||
/*
|
||||
* spa_refcount & spa_config_lock must be the last elements
|
||||
|
||||
Reference in New Issue
Block a user