Skip to content

Commit 2508daf

Browse files
committed
Activate per-dataset feature flags when the property is set
If a compression algorithm requires a feature flag, activate the feature when the property is set, rather than waiting for the first block to be born. This is currently only used by zstd but can be extended as needed. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Allan Jude <allanjude@freebsd.org>
1 parent b8bec3f commit 2508daf

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

include/sys/dsl_dataset.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ int dsl_dataset_set_refquota(const char *dsname, zprop_source_t source,
435435
uint64_t quota);
436436
int dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source,
437437
uint64_t reservation);
438+
int dsl_dataset_set_compression(const char *dsname, zprop_source_t source,
439+
uint64_t compression);
438440

439441
boolean_t dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier,
440442
uint64_t earlier_txg);

module/zfs/dsl_dataset.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
* Copyright 2017 Nexenta Systems, Inc.
3131
* Copyright (c) 2019, Klara Inc.
3232
* Copyright (c) 2019, Allan Jude
33+
* Copyright (c) 2020 The FreeBSD Foundation [1]
34+
*
35+
* [1] Portions of this software were developed by Allan Jude
36+
* under sponsorship from the FreeBSD Foundation.
3337
*/
3438

3539
#include <sys/dmu_objset.h>
@@ -4518,6 +4522,73 @@ dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source,
45184522
ZFS_SPACE_CHECK_EXTRA_RESERVED));
45194523
}
45204524

4525+
typedef struct dsl_dataset_set_compression_arg {
4526+
const char *ddsca_name;
4527+
zprop_source_t ddsca_source;
4528+
uint64_t ddsca_value;
4529+
} dsl_dataset_set_compression_arg_t;
4530+
4531+
/* ARGSUSED */
4532+
static int
4533+
dsl_dataset_set_compression_check(void *arg, dmu_tx_t *tx)
4534+
{
4535+
dsl_dataset_set_compression_arg_t *ddsca = arg;
4536+
dsl_pool_t *dp = dmu_tx_pool(tx);
4537+
4538+
uint64_t compval = ZIO_COMPRESS_ALGO(ddsca->ddsca_value);
4539+
spa_feature_t f = zio_compress_to_feature(compval);
4540+
4541+
if (f == SPA_FEATURE_NONE)
4542+
return (SET_ERROR(EINVAL));
4543+
4544+
if (!spa_feature_is_enabled(dp->dp_spa, f))
4545+
return (SET_ERROR(ENOTSUP));
4546+
4547+
return (0);
4548+
}
4549+
4550+
static void
4551+
dsl_dataset_set_compression_sync(void *arg, dmu_tx_t *tx)
4552+
{
4553+
dsl_dataset_set_compression_arg_t *ddsca = arg;
4554+
dsl_pool_t *dp = dmu_tx_pool(tx);
4555+
dsl_dataset_t *ds = NULL;
4556+
4557+
uint64_t compval = ZIO_COMPRESS_ALGO(ddsca->ddsca_value);
4558+
spa_feature_t f = zio_compress_to_feature(compval);
4559+
ASSERT3S(spa_feature_table[f].fi_type, ==, ZFEATURE_TYPE_BOOLEAN);
4560+
4561+
VERIFY0(dsl_dataset_hold(dp, ddsca->ddsca_name, FTAG, &ds));
4562+
if (zfeature_active(f, ds->ds_feature[f]) != B_TRUE) {
4563+
dsl_dataset_activate_feature(ds->ds_object, f,
4564+
ds->ds_feature_activation[f], tx);
4565+
ds->ds_feature[f] = ds->ds_feature_activation[f];
4566+
}
4567+
dsl_dataset_rele(ds, FTAG);
4568+
}
4569+
4570+
int
4571+
dsl_dataset_set_compression(const char *dsname, zprop_source_t source,
4572+
uint64_t compression)
4573+
{
4574+
dsl_dataset_set_compression_arg_t ddsca;
4575+
4576+
/*
4577+
* The sync task is only required for zstd in order to activate
4578+
* the feature flag when the property is first set.
4579+
*/
4580+
if (ZIO_COMPRESS_ALGO(compression) != ZIO_COMPRESS_ZSTD)
4581+
return (0);
4582+
4583+
ddsca.ddsca_name = dsname;
4584+
ddsca.ddsca_source = source;
4585+
ddsca.ddsca_value = compression;
4586+
4587+
return (dsl_sync_task(dsname, dsl_dataset_set_compression_check,
4588+
dsl_dataset_set_compression_sync, &ddsca, 0,
4589+
ZFS_SPACE_CHECK_EXTRA_RESERVED));
4590+
}
4591+
45214592
/*
45224593
* Return (in *usedp) the amount of space referenced by "new" that was not
45234594
* referenced at the time the bookmark corresponds to. "New" may be a

module/zfs/zfs_ioctl.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,9 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
24822482
case ZFS_PROP_REFRESERVATION:
24832483
err = dsl_dataset_set_refreservation(dsname, source, intval);
24842484
break;
2485+
case ZFS_PROP_COMPRESSION:
2486+
err = dsl_dataset_set_compression(dsname, source, intval);
2487+
break;
24852488
case ZFS_PROP_VOLSIZE:
24862489
err = zvol_set_volsize(dsname, intval);
24872490
break;

0 commit comments

Comments
 (0)