aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/module/zfs/spa.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/spa.c')
-rw-r--r--sys/contrib/openzfs/module/zfs/spa.c82
1 files changed, 66 insertions, 16 deletions
diff --git a/sys/contrib/openzfs/module/zfs/spa.c b/sys/contrib/openzfs/module/zfs/spa.c
index bbb83fc610b1..dc202978c0f6 100644
--- a/sys/contrib/openzfs/module/zfs/spa.c
+++ b/sys/contrib/openzfs/module/zfs/spa.c
@@ -52,6 +52,7 @@
#include <sys/dmu_tx.h>
#include <sys/zap.h>
#include <sys/zil.h>
+#include <sys/brt.h>
#include <sys/ddt.h>
#include <sys/vdev_impl.h>
#include <sys/vdev_removal.h>
@@ -341,6 +342,12 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
spa_prop_add_list(*nvp, ZPOOL_PROP_DEDUPRATIO, NULL,
ddt_get_pool_dedup_ratio(spa), src);
+ spa_prop_add_list(*nvp, ZPOOL_PROP_BCLONEUSED, NULL,
+ brt_get_used(spa), src);
+ spa_prop_add_list(*nvp, ZPOOL_PROP_BCLONESAVED, NULL,
+ brt_get_saved(spa), src);
+ spa_prop_add_list(*nvp, ZPOOL_PROP_BCLONERATIO, NULL,
+ brt_get_ratio(spa), src);
spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
rvd->vdev_state, src);
@@ -543,7 +550,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
elem = NULL;
while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
uint64_t intval;
- char *strval, *slash, *check, *fname;
+ const char *strval, *slash, *check, *fname;
const char *propname = nvpair_name(elem);
zpool_prop_t prop = zpool_name_to_prop(propname);
@@ -745,7 +752,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props)
void
spa_configfile_set(spa_t *spa, nvlist_t *nvp, boolean_t need_sync)
{
- char *cachefile;
+ const char *cachefile;
spa_config_dirent_t *dp;
if (nvlist_lookup_string(nvp, zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
@@ -1707,6 +1714,7 @@ spa_unload(spa_t *spa)
}
ddt_unload(spa);
+ brt_unload(spa);
spa_unload_log_sm_metadata(spa);
/*
@@ -3343,7 +3351,7 @@ static int
spa_verify_host(spa_t *spa, nvlist_t *mos_config)
{
uint64_t hostid;
- char *hostname;
+ const char *hostname;
uint64_t myhostid = 0;
if (!spa_is_root(spa) && nvlist_lookup_uint64(mos_config,
@@ -3378,8 +3386,8 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type)
int parse;
vdev_t *rvd;
uint64_t pool_guid;
- char *comment;
- char *compatibility;
+ const char *comment;
+ const char *compatibility;
/*
* Versioning wasn't explicitly added to the label until later, so if
@@ -4415,6 +4423,21 @@ spa_ld_load_dedup_tables(spa_t *spa)
}
static int
+spa_ld_load_brt(spa_t *spa)
+{
+ int error = 0;
+ vdev_t *rvd = spa->spa_root_vdev;
+
+ error = brt_load(spa);
+ if (error != 0) {
+ spa_load_failed(spa, "brt_load failed [error=%d]", error);
+ return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
+ }
+
+ return (0);
+}
+
+static int
spa_ld_verify_logs(spa_t *spa, spa_import_type_t type, const char **ereport)
{
vdev_t *rvd = spa->spa_root_vdev;
@@ -4895,6 +4918,10 @@ spa_load_impl(spa_t *spa, spa_import_type_t type, const char **ereport)
if (error != 0)
return (error);
+ error = spa_ld_load_brt(spa);
+ if (error != 0)
+ return (error);
+
/*
* Verify the logs now to make sure we don't have any unexpected errors
* when we claim log blocks later.
@@ -5366,13 +5393,15 @@ spa_add_spares(spa_t *spa, nvlist_t *config)
for (i = 0; i < nspares; i++) {
guid = fnvlist_lookup_uint64(spares[i],
ZPOOL_CONFIG_GUID);
+ VERIFY0(nvlist_lookup_uint64_array(spares[i],
+ ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc));
if (spa_spare_exists(guid, &pool, NULL) &&
pool != 0ULL) {
- VERIFY0(nvlist_lookup_uint64_array(spares[i],
- ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs,
- &vsc));
vs->vs_state = VDEV_STATE_CANT_OPEN;
vs->vs_aux = VDEV_AUX_SPARED;
+ } else {
+ vs->vs_state =
+ spa->spa_spares.sav_vdevs[i]->vdev_state;
}
}
}
@@ -5770,7 +5799,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
nvlist_t *zplprops, dsl_crypto_params_t *dcp)
{
spa_t *spa;
- char *altroot = NULL;
+ const char *altroot = NULL;
vdev_t *rvd;
dsl_pool_t *dp;
dmu_tx_t *tx;
@@ -5783,8 +5812,8 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
boolean_t has_encryption;
boolean_t has_allocclass;
spa_feature_t feat;
- char *feat_name;
- char *poolname;
+ const char *feat_name;
+ const char *poolname;
nvlist_t *nvl;
if (props == NULL ||
@@ -5963,6 +5992,10 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
* Create DDTs (dedup tables).
*/
ddt_create(spa);
+ /*
+ * Create BRT table and BRT table object.
+ */
+ brt_create(spa);
spa_update_dspace(spa);
@@ -6079,7 +6112,7 @@ int
spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
{
spa_t *spa;
- char *altroot = NULL;
+ const char *altroot = NULL;
spa_load_state_t state = SPA_LOAD_IMPORT;
zpool_load_policy_t policy;
spa_mode_t mode = spa_mode_global;
@@ -6259,7 +6292,7 @@ nvlist_t *
spa_tryimport(nvlist_t *tryconfig)
{
nvlist_t *config = NULL;
- char *poolname, *cachefile;
+ const char *poolname, *cachefile;
spa_t *spa;
uint64_t state;
int error;
@@ -7532,7 +7565,7 @@ spa_vdev_split_mirror(spa_t *spa, const char *newname, nvlist_t *config,
uint_t c, children, lastlog;
nvlist_t **child, *nvl, *tmp;
dmu_tx_t *tx;
- char *altroot = NULL;
+ const char *altroot = NULL;
vdev_t *rvd, **vml = NULL; /* vdev modify list */
boolean_t activate_slog;
@@ -8752,7 +8785,7 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
while ((elem = nvlist_next_nvpair(nvp, elem))) {
uint64_t intval;
- char *strval, *fname;
+ const char *strval, *fname;
zpool_prop_t prop;
const char *propname;
zprop_type_t proptype;
@@ -9138,6 +9171,7 @@ spa_sync_iterate_to_convergence(spa_t *spa, dmu_tx_t *tx)
&spa->spa_deferred_bpobj, tx);
}
+ brt_sync(spa, txg);
ddt_sync(spa, txg);
dsl_scan_sync(dp, tx);
svr_sync(spa, tx);
@@ -9263,6 +9297,13 @@ spa_sync(spa_t *spa, uint64_t txg)
ZIO_FLAG_CANFAIL);
/*
+ * Now that there can be no more cloning in this transaction group,
+ * but we are still before issuing frees, we can process pending BRT
+ * updates.
+ */
+ brt_pending_apply(spa, txg);
+
+ /*
* Lock out configuration changes.
*/
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
@@ -9281,7 +9322,13 @@ spa_sync(spa_t *spa, uint64_t txg)
* into config changes that go out with this transaction group.
*/
spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
- while (list_head(&spa->spa_state_dirty_list) != NULL) {
+ while ((vd = list_head(&spa->spa_state_dirty_list)) != NULL) {
+ /* Avoid holding the write lock unless actually necessary */
+ if (vd->vdev_aux == NULL) {
+ vdev_state_clean(vd);
+ vdev_config_dirty(vd);
+ continue;
+ }
/*
* We need the write lock here because, for aux vdevs,
* calling vdev_config_dirty() modifies sav_config.
@@ -9402,6 +9449,9 @@ spa_sync(spa_t *spa, uint64_t txg)
spa_update_dspace(spa);
+ if (spa_get_autotrim(spa) == SPA_AUTOTRIM_ON)
+ vdev_autotrim_kick(spa);
+
/*
* It had better be the case that we didn't dirty anything
* since vdev_config_sync().