mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +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:
@@ -2921,7 +2921,9 @@
|
||||
<enumerator name='ZPOOL_PROP_BCLONEUSED' value='33'/>
|
||||
<enumerator name='ZPOOL_PROP_BCLONESAVED' value='34'/>
|
||||
<enumerator name='ZPOOL_PROP_BCLONERATIO' value='35'/>
|
||||
<enumerator name='ZPOOL_NUM_PROPS' value='36'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_TABLE_SIZE' value='36'/>
|
||||
<enumerator name='ZPOOL_PROP_DEDUP_TABLE_QUOTA' value='37'/>
|
||||
<enumerator name='ZPOOL_NUM_PROPS' value='38'/>
|
||||
</enum-decl>
|
||||
<typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
|
||||
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>
|
||||
|
||||
@@ -332,6 +332,24 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
|
||||
intval = zpool_get_prop_int(zhp, prop, &src);
|
||||
|
||||
switch (prop) {
|
||||
case ZPOOL_PROP_DEDUP_TABLE_QUOTA:
|
||||
/*
|
||||
* If dedup quota is 0, we translate this into 'none'
|
||||
* (unless literal is set). And if it is UINT64_MAX
|
||||
* we translate that as 'automatic' (limit to size of
|
||||
* the dedicated dedup VDEV. Otherwise, fall throught
|
||||
* into the regular number formating.
|
||||
*/
|
||||
if (intval == 0) {
|
||||
(void) strlcpy(buf, literal ? "0" : "none",
|
||||
len);
|
||||
break;
|
||||
} else if (intval == UINT64_MAX) {
|
||||
(void) strlcpy(buf, "auto", len);
|
||||
break;
|
||||
}
|
||||
zfs_fallthrough;
|
||||
|
||||
case ZPOOL_PROP_SIZE:
|
||||
case ZPOOL_PROP_ALLOCATED:
|
||||
case ZPOOL_PROP_FREE:
|
||||
@@ -342,6 +360,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
|
||||
case ZPOOL_PROP_MAXDNODESIZE:
|
||||
case ZPOOL_PROP_BCLONESAVED:
|
||||
case ZPOOL_PROP_BCLONEUSED:
|
||||
case ZPOOL_PROP_DEDUP_TABLE_SIZE:
|
||||
if (literal)
|
||||
(void) snprintf(buf, len, "%llu",
|
||||
(u_longlong_t)intval);
|
||||
|
||||
@@ -1691,6 +1691,16 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
|
||||
"use 'none' to disable quota/refquota"));
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* Pool dedup table quota; force use of 'none' instead of 0
|
||||
*/
|
||||
if ((type & ZFS_TYPE_POOL) && *ivalp == 0 &&
|
||||
(!isnone && !isauto) &&
|
||||
prop == ZPOOL_PROP_DEDUP_TABLE_QUOTA) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"use 'none' to disable ddt table quota"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special handling for "*_limit=none". In this case it's not
|
||||
@@ -1732,6 +1742,10 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
|
||||
}
|
||||
*ivalp = UINT64_MAX;
|
||||
break;
|
||||
case ZPOOL_PROP_DEDUP_TABLE_QUOTA:
|
||||
ASSERT(type & ZFS_TYPE_POOL);
|
||||
*ivalp = UINT64_MAX;
|
||||
break;
|
||||
default:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'auto' is invalid value for '%s'"),
|
||||
|
||||
Reference in New Issue
Block a user