|
30 | 30 | * Copyright 2017 Nexenta Systems, Inc. |
31 | 31 | * Copyright (c) 2019, Klara Inc. |
32 | 32 | * 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. |
33 | 37 | */ |
34 | 38 |
|
35 | 39 | #include <sys/dmu_objset.h> |
@@ -4518,6 +4522,73 @@ dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source, |
4518 | 4522 | ZFS_SPACE_CHECK_EXTRA_RESERVED)); |
4519 | 4523 | } |
4520 | 4524 |
|
| 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 | + |
4521 | 4592 | /* |
4522 | 4593 | * Return (in *usedp) the amount of space referenced by "new" that was not |
4523 | 4594 | * referenced at the time the bookmark corresponds to. "New" may be a |
|
0 commit comments