mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Pool allocation classes
Allocation Classes add the ability to have allocation classes in a pool that are dedicated to serving specific block categories, such as DDT data, metadata, and small file blocks. A pool can opt-in to this feature by adding a 'special' or 'dedup' top-level VDEV. Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Reviewed-by: Alek Pinchuk <apinchuk@datto.com> Reviewed-by: Håkan Johansson <f96hajo@chalmers.se> Reviewed-by: Andreas Dilger <andreas.dilger@chamcloud.com> Reviewed-by: DHE <git@dehacked.net> Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com> Reviewed-by: Gregor Kopka <gregor@kopka.net> Reviewed-by: Kash Pande <kash@tripleback.net> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Signed-off-by: Don Brady <don.brady@delphix.com> Closes #5182
This commit is contained in:
committed by
Brian Behlendorf
parent
cfa37548eb
commit
cc99f275a2
@@ -21,7 +21,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
@@ -944,8 +944,18 @@ spa_vdev_copy_segment(vdev_t *vd, range_tree_t *segs,
|
||||
}
|
||||
ASSERT3U(size, <=, maxalloc);
|
||||
|
||||
int error = metaslab_alloc_dva(spa, mg->mg_class, size,
|
||||
&dst, 0, NULL, txg, 0, zal, 0);
|
||||
/*
|
||||
* An allocation class might not have any remaining vdevs or space
|
||||
*/
|
||||
metaslab_class_t *mc = mg->mg_class;
|
||||
if (mc != spa_normal_class(spa) && mc->mc_groups <= 1)
|
||||
mc = spa_normal_class(spa);
|
||||
int error = metaslab_alloc_dva(spa, mc, size, &dst, 0, NULL, txg, 0,
|
||||
zal, 0);
|
||||
if (error == ENOSPC && mc != spa_normal_class(spa)) {
|
||||
error = metaslab_alloc_dva(spa, spa_normal_class(spa), size,
|
||||
&dst, 0, NULL, txg, 0, zal, 0);
|
||||
}
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
@@ -1853,15 +1863,31 @@ spa_vdev_remove_top_check(vdev_t *vd)
|
||||
if (!spa_feature_is_enabled(spa, SPA_FEATURE_DEVICE_REMOVAL))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
|
||||
/* available space in the pool's normal class */
|
||||
uint64_t available = dsl_dir_space_available(
|
||||
spa->spa_dsl_pool->dp_root_dir, NULL, 0, B_TRUE);
|
||||
|
||||
metaslab_class_t *mc = vd->vdev_mg->mg_class;
|
||||
|
||||
/*
|
||||
* When removing a vdev from an allocation class that has
|
||||
* remaining vdevs, include available space from the class.
|
||||
*/
|
||||
if (mc != spa_normal_class(spa) && mc->mc_groups > 1) {
|
||||
uint64_t class_avail = metaslab_class_get_space(mc) -
|
||||
metaslab_class_get_alloc(mc);
|
||||
|
||||
/* add class space, adjusted for overhead */
|
||||
available += (class_avail * 94) / 100;
|
||||
}
|
||||
|
||||
/*
|
||||
* There has to be enough free space to remove the
|
||||
* device and leave double the "slop" space (i.e. we
|
||||
* must leave at least 3% of the pool free, in addition to
|
||||
* the normal slop space).
|
||||
*/
|
||||
if (dsl_dir_space_available(spa->spa_dsl_pool->dp_root_dir,
|
||||
NULL, 0, B_TRUE) <
|
||||
vd->vdev_stat.vs_dspace + spa_get_slop_space(spa)) {
|
||||
if (available < vd->vdev_stat.vs_dspace + spa_get_slop_space(spa)) {
|
||||
return (SET_ERROR(ENOSPC));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user