diff options
author | Matthew Ahrens <[email protected]> | 2015-07-24 09:53:55 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-12-04 14:20:20 -0800 |
commit | 241b5415748859a3c272fc8f570f2368e93adde9 (patch) | |
tree | 6a30a5f475473533660c1680f1cc8cbb27e65056 /module | |
parent | 072484504fa3c905f5d3712abff765cf33c1e72d (diff) |
Illumos 5959 - clean up per-dataset feature count code
5959 clean up per-dataset feature count code
Reviewed by: Toomas Soome <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Alex Reece <[email protected]>
Approved by: Richard Lowe <[email protected]>
References:
https://www.illumos.org/issues/5959
https://github.com/illumos/illumos-gate/commit/ca0cc39
Porting notes:
illumos code doesn't check for feature_get_refcount() returning
ENOTSUP (which means feature is disabled) in zdb. zfsonlinux added
a check in https://github.com/zfsonlinux/zfs/commit/784652c
due to #3468. The check was reintroduced here.
Ported-by: Witaut Bajaryn <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3965
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/dbuf.c | 5 | ||||
-rw-r--r-- | module/zfs/dmu_send.c | 11 | ||||
-rw-r--r-- | module/zfs/dsl_dataset.c | 198 | ||||
-rw-r--r-- | module/zfs/dsl_destroy.c | 24 | ||||
-rw-r--r-- | module/zfs/zfeature.c | 16 | ||||
-rw-r--r-- | module/zfs/zfeature_common.c | 50 |
6 files changed, 163 insertions, 141 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index d340da821..31242d601 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -1615,6 +1615,11 @@ dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data, struct dirty_leaf *dl; dmu_object_type_t type; + if (etype == BP_EMBEDDED_TYPE_DATA) { + ASSERT(spa_feature_is_active(dmu_objset_spa(db->db_objset), + SPA_FEATURE_EMBEDDED_DATA)); + } + DB_DNODE_ENTER(db); type = DB_DNODE(db)->dn_type; DB_DNODE_EXIT(db); diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index b2d844eb4..8e79dc70d 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2014 by Delphix. All rights reserved. @@ -611,7 +611,7 @@ dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *ds, } #endif - if (large_block_ok && ds->ds_large_blocks) + if (large_block_ok && ds->ds_feature_inuse[SPA_FEATURE_LARGE_BLOCKS]) featureflags |= DMU_BACKUP_FEATURE_LARGE_BLOCKS; if (embedok && spa_feature_is_active(dp->dp_spa, SPA_FEATURE_EMBEDDED_DATA)) { @@ -1226,13 +1226,6 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx) } VERIFY0(dsl_dataset_own_obj(dp, dsobj, dmu_recv_tag, &newds)); - if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) & - DMU_BACKUP_FEATURE_LARGE_BLOCKS) && - !newds->ds_large_blocks) { - dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx); - newds->ds_large_blocks = B_TRUE; - } - dmu_buf_will_dirty(newds->ds_dbuf, tx); dsl_dataset_phys(newds)->ds_flags |= DS_FLAG_INCONSISTENT; diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 2168f2894..829452b1d 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2014 RackTop Systems. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. @@ -126,8 +126,10 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx) dsl_dataset_phys(ds)->ds_compressed_bytes += compressed; dsl_dataset_phys(ds)->ds_uncompressed_bytes += uncompressed; dsl_dataset_phys(ds)->ds_unique_bytes += used; - if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE) - ds->ds_need_large_blocks = B_TRUE; + if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE) { + ds->ds_feature_activation_needed[SPA_FEATURE_LARGE_BLOCKS] = + B_TRUE; + } mutex_exit(&ds->ds_lock); dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta, compressed, uncompressed, tx); @@ -432,19 +434,25 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag, offsetof(dmu_sendarg_t, dsa_link)); if (doi.doi_type == DMU_OTN_ZAP_METADATA) { - int zaperr = zap_contains(mos, dsobj, - DS_FIELD_LARGE_BLOCKS); - if (zaperr != ENOENT) { - VERIFY0(zaperr); - ds->ds_large_blocks = B_TRUE; + spa_feature_t f; + + for (f = 0; f < SPA_FEATURES; f++) { + if (!(spa_feature_table[f].fi_flags & + ZFEATURE_FLAG_PER_DATASET)) + continue; + err = zap_contains(mos, dsobj, + spa_feature_table[f].fi_guid); + if (err == 0) { + ds->ds_feature_inuse[f] = B_TRUE; + } else { + ASSERT3U(err, ==, ENOENT); + err = 0; + } } } - if (err == 0) { - err = dsl_dir_hold_obj(dp, - dsl_dataset_phys(ds)->ds_dir_obj, NULL, ds, - &ds->ds_dir); - } + err = dsl_dir_hold_obj(dp, + dsl_dataset_phys(ds)->ds_dir_obj, NULL, ds, &ds->ds_dir); if (err != 0) { mutex_destroy(&ds->ds_lock); mutex_destroy(&ds->ds_opening_lock); @@ -698,6 +706,34 @@ dsl_dataset_tryown(dsl_dataset_t *ds, void *tag) return (gotit); } +static void +dsl_dataset_activate_feature(uint64_t dsobj, spa_feature_t f, dmu_tx_t *tx) +{ + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset; + uint64_t zero = 0; + + VERIFY(spa_feature_table[f].fi_flags & ZFEATURE_FLAG_PER_DATASET); + + spa_feature_incr(spa, f, tx); + dmu_object_zapify(mos, dsobj, DMU_OT_DSL_DATASET, tx); + + VERIFY0(zap_add(mos, dsobj, spa_feature_table[f].fi_guid, + sizeof (zero), 1, &zero, tx)); +} + +void +dsl_dataset_deactivate_feature(uint64_t dsobj, spa_feature_t f, dmu_tx_t *tx) +{ + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset; + + VERIFY(spa_feature_table[f].fi_flags & ZFEATURE_FLAG_PER_DATASET); + + VERIFY0(zap_remove(mos, dsobj, spa_feature_table[f].fi_guid, tx)); + spa_feature_decr(spa, f, tx); +} + uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, uint64_t flags, dmu_tx_t *tx) @@ -736,6 +772,7 @@ dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, if (origin == NULL) { dsphys->ds_deadlist_obj = dsl_deadlist_alloc(mos, tx); } else { + spa_feature_t f; dsl_dataset_t *ohds; /* head of the origin snapshot */ dsphys->ds_prev_snap_obj = origin->ds_object; @@ -756,8 +793,10 @@ dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, dsphys->ds_flags |= dsl_dataset_phys(origin)->ds_flags & (DS_FLAG_INCONSISTENT | DS_FLAG_CI_DATASET); - if (origin->ds_large_blocks) - dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx); + for (f = 0; f < SPA_FEATURES; f++) { + if (origin->ds_feature_inuse[f]) + dsl_dataset_activate_feature(dsobj, f, tx); + } dmu_buf_will_dirty(origin->ds_dbuf, tx); dsl_dataset_phys(origin)->ds_num_children++; @@ -1233,6 +1272,7 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, dsl_dataset_phys_t *dsphys; uint64_t dsobj, crtxg; objset_t *mos = dp->dp_meta_objset; + spa_feature_t f; ASSERTV(static zil_header_t zero_zil); ASSERTV(objset_t *os); @@ -1282,8 +1322,10 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, dsphys->ds_bp = dsl_dataset_phys(ds)->ds_bp; dmu_buf_rele(dbuf, FTAG); - if (ds->ds_large_blocks) - dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx); + for (f = 0; f < SPA_FEATURES; f++) { + if (ds->ds_feature_inuse[f]) + dsl_dataset_activate_feature(dsobj, f, tx); + } ASSERT3U(ds->ds_prev != 0, ==, dsl_dataset_phys(ds)->ds_prev_snap_obj != 0); @@ -1561,6 +1603,8 @@ dsl_dataset_snapshot_tmp(const char *fsname, const char *snapname, void dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) { + spa_feature_t f; + ASSERT(dmu_tx_is_syncing(tx)); ASSERT(ds->ds_objset != NULL); ASSERT(dsl_dataset_phys(ds)->ds_next_snap_obj == 0); @@ -1574,9 +1618,13 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) dmu_objset_sync(ds->ds_objset, zio, tx); - if (ds->ds_need_large_blocks && !ds->ds_large_blocks) { - dsl_dataset_activate_large_blocks_sync_impl(ds->ds_object, tx); - ds->ds_large_blocks = B_TRUE; + for (f = 0; f < SPA_FEATURES; f++) { + if (ds->ds_feature_activation_needed[f]) { + if (ds->ds_feature_inuse[f]) + continue; + dsl_dataset_activate_feature(ds->ds_object, f, tx); + ds->ds_feature_inuse[f] = B_TRUE; + } } } @@ -2703,6 +2751,7 @@ void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone, dsl_dataset_t *origin_head, dmu_tx_t *tx) { + spa_feature_t f; dsl_pool_t *dp = dmu_tx_pool(tx); int64_t unused_refres_delta; @@ -2711,6 +2760,43 @@ dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone, dsl_dataset_phys(clone)->ds_unique_bytes <= origin_head->ds_quota); ASSERT3P(clone->ds_prev, ==, origin_head->ds_prev); + /* + * Swap per-dataset feature flags. + */ + for (f = 0; f < SPA_FEATURES; f++) { + boolean_t clone_inuse; + boolean_t origin_head_inuse; + + if (!(spa_feature_table[f].fi_flags & + ZFEATURE_FLAG_PER_DATASET)) { + ASSERT(!clone->ds_feature_inuse[f]); + ASSERT(!origin_head->ds_feature_inuse[f]); + continue; + } + + clone_inuse = clone->ds_feature_inuse[f]; + origin_head_inuse = origin_head->ds_feature_inuse[f]; + + if (clone_inuse) { + dsl_dataset_deactivate_feature(clone->ds_object, f, tx); + clone->ds_feature_inuse[f] = B_FALSE; + } + if (origin_head_inuse) { + dsl_dataset_deactivate_feature(origin_head->ds_object, + f, tx); + origin_head->ds_feature_inuse[f] = B_FALSE; + } + if (clone_inuse) { + dsl_dataset_activate_feature(origin_head->ds_object, + f, tx); + origin_head->ds_feature_inuse[f] = B_TRUE; + } + if (origin_head_inuse) { + dsl_dataset_activate_feature(clone->ds_object, f, tx); + clone->ds_feature_inuse[f] = B_TRUE; + } + } + dmu_buf_will_dirty(clone->ds_dbuf, tx); dmu_buf_will_dirty(origin_head->ds_dbuf, tx); @@ -3265,77 +3351,6 @@ dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, return (err); } -static int -dsl_dataset_activate_large_blocks_check(void *arg, dmu_tx_t *tx) -{ - const char *dsname = arg; - dsl_dataset_t *ds; - dsl_pool_t *dp = dmu_tx_pool(tx); - int error = 0; - - if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS)) - return (SET_ERROR(ENOTSUP)); - - ASSERT(spa_feature_is_enabled(dp->dp_spa, - SPA_FEATURE_EXTENSIBLE_DATASET)); - - error = dsl_dataset_hold(dp, dsname, FTAG, &ds); - if (error != 0) - return (error); - - if (ds->ds_large_blocks) - error = EALREADY; - dsl_dataset_rele(ds, FTAG); - - return (error); -} - -void -dsl_dataset_activate_large_blocks_sync_impl(uint64_t dsobj, dmu_tx_t *tx) -{ - spa_t *spa = dmu_tx_pool(tx)->dp_spa; - objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset; - uint64_t zero = 0; - - spa_feature_incr(spa, SPA_FEATURE_LARGE_BLOCKS, tx); - dmu_object_zapify(mos, dsobj, DMU_OT_DSL_DATASET, tx); - - VERIFY0(zap_add(mos, dsobj, DS_FIELD_LARGE_BLOCKS, - sizeof (zero), 1, &zero, tx)); -} - -static void -dsl_dataset_activate_large_blocks_sync(void *arg, dmu_tx_t *tx) -{ - const char *dsname = arg; - dsl_dataset_t *ds; - - VERIFY0(dsl_dataset_hold(dmu_tx_pool(tx), dsname, FTAG, &ds)); - - dsl_dataset_activate_large_blocks_sync_impl(ds->ds_object, tx); - ASSERT(!ds->ds_large_blocks); - ds->ds_large_blocks = B_TRUE; - dsl_dataset_rele(ds, FTAG); -} - -int -dsl_dataset_activate_large_blocks(const char *dsname) -{ - int error; - - error = dsl_sync_task(dsname, - dsl_dataset_activate_large_blocks_check, - dsl_dataset_activate_large_blocks_sync, (void *)dsname, - 1, ZFS_SPACE_CHECK_RESERVED); - - /* - * EALREADY indicates that this dataset already supports large blocks. - */ - if (error == EALREADY) - error = 0; - return (error); -} - /* * Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline. * For example, they could both be snapshots of the same filesystem, and @@ -3380,7 +3395,6 @@ dsl_dataset_is_before(dsl_dataset_t *later, dsl_dataset_t *earlier, return (ret); } - void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx) { diff --git a/module/zfs/dsl_destroy.c b/module/zfs/dsl_destroy.c index 0e2238f99..e45f46d8d 100644 --- a/module/zfs/dsl_destroy.c +++ b/module/zfs/dsl_destroy.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2013 by Joyent, Inc. All rights reserved. */ @@ -246,6 +246,7 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx) #ifdef ZFS_DEBUG int err; #endif + spa_feature_t f; int after_branch_point = FALSE; dsl_pool_t *dp = ds->ds_dir->dd_pool; objset_t *mos = dp->dp_meta_objset; @@ -277,9 +278,11 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx) obj = ds->ds_object; - if (ds->ds_large_blocks) { - ASSERT0(zap_contains(mos, obj, DS_FIELD_LARGE_BLOCKS)); - spa_feature_decr(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS, tx); + for (f = 0; f < SPA_FEATURES; f++) { + if (ds->ds_feature_inuse[f]) { + dsl_dataset_deactivate_feature(obj, f, tx); + ds->ds_feature_inuse[f] = B_FALSE; + } } if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) { ASSERT3P(ds->ds_prev, ==, NULL); @@ -715,6 +718,7 @@ void dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx) { dsl_pool_t *dp = dmu_tx_pool(tx); + spa_feature_t f; objset_t *mos = dp->dp_meta_objset; uint64_t obj, ddobj, prevobj = 0; boolean_t rmorigin; @@ -742,12 +746,16 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx) ASSERT0(ds->ds_reserved); } - if (ds->ds_large_blocks) - spa_feature_decr(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS, tx); + obj = ds->ds_object; - dsl_scan_ds_destroyed(ds, tx); + for (f = 0; f < SPA_FEATURES; f++) { + if (ds->ds_feature_inuse[f]) { + dsl_dataset_deactivate_feature(obj, f, tx); + ds->ds_feature_inuse[f] = B_FALSE; + } + } - obj = ds->ds_object; + dsl_scan_ds_destroyed(ds, tx); if (dsl_dataset_phys(ds)->ds_prev_snap_obj != 0) { /* This is a clone */ diff --git a/module/zfs/zfeature.c b/module/zfs/zfeature.c index 352376f22..bda954829 100644 --- a/module/zfs/zfeature.c +++ b/module/zfs/zfeature.c @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. */ #include <sys/zfs_context.h> @@ -253,7 +253,7 @@ feature_get_refcount_from_disk(spa_t *spa, zfeature_info_t *feature, { int err; uint64_t refcount; - uint64_t zapobj = feature->fi_can_readonly ? + uint64_t zapobj = (feature->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; /* @@ -306,7 +306,7 @@ feature_sync(spa_t *spa, zfeature_info_t *feature, uint64_t refcount, uint64_t zapobj; ASSERT(VALID_FEATURE_OR_NONE(feature->fi_feature)); - zapobj = feature->fi_can_readonly ? + zapobj = (feature->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; VERIFY0(zap_update(spa->spa_meta_objset, zapobj, feature->fi_guid, sizeof (uint64_t), 1, &refcount, tx)); @@ -327,7 +327,7 @@ feature_sync(spa_t *spa, zfeature_info_t *feature, uint64_t refcount, if (refcount == 0) spa_deactivate_mos_feature(spa, feature->fi_guid); - else if (feature->fi_mos) + else if (feature->fi_flags & ZFEATURE_FLAG_MOS) spa_activate_mos_feature(spa, feature->fi_guid, tx); } @@ -338,8 +338,9 @@ feature_sync(spa_t *spa, zfeature_info_t *feature, uint64_t refcount, void feature_enable_sync(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx) { - uint64_t initial_refcount = feature->fi_activate_on_enable ? 1 : 0; - uint64_t zapobj = feature->fi_can_readonly ? + uint64_t initial_refcount = + (feature->fi_flags & ZFEATURE_FLAG_ACTIVATE_ON_ENABLE) ? 1 : 0; + uint64_t zapobj = (feature->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; int i; @@ -385,7 +386,8 @@ feature_do_action(spa_t *spa, spa_feature_t fid, feature_action_t action, { uint64_t refcount = 0; zfeature_info_t *feature = &spa_feature_table[fid]; - ASSERTV(uint64_t zapobj = feature->fi_can_readonly ? + ASSERTV(uint64_t zapobj = + (feature->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj); ASSERT(VALID_FEATURE_FID(fid)); diff --git a/module/zfs/zfeature_common.c b/module/zfs/zfeature_common.c index 609a72ab3..f57e5489c 100644 --- a/module/zfs/zfeature_common.c +++ b/module/zfs/zfeature_common.c @@ -20,7 +20,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2015 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved. */ @@ -135,15 +135,15 @@ zfeature_depends_on(spa_feature_t fid, spa_feature_t check) { static void zfeature_register(spa_feature_t fid, const char *guid, const char *name, - const char *desc, boolean_t readonly, boolean_t mos, - boolean_t activate_on_enable, const spa_feature_t *deps) + const char *desc, zfeature_flags_t flags, const spa_feature_t *deps) { zfeature_info_t *feature = &spa_feature_table[fid]; static spa_feature_t nodeps[] = { SPA_FEATURE_NONE }; ASSERT(name != NULL); ASSERT(desc != NULL); - ASSERT(!readonly || !mos); + ASSERT((flags & ZFEATURE_FLAG_READONLY_COMPAT) == 0 || + (flags & ZFEATURE_FLAG_MOS) == 0); ASSERT3U(fid, <, SPA_FEATURES); ASSERT(zfeature_is_valid_guid(guid)); @@ -154,9 +154,7 @@ zfeature_register(spa_feature_t fid, const char *guid, const char *name, feature->fi_guid = guid; feature->fi_uname = name; feature->fi_desc = desc; - feature->fi_can_readonly = readonly; - feature->fi_mos = mos; - feature->fi_activate_on_enable = activate_on_enable; + feature->fi_flags = flags; feature->fi_depends = deps; } @@ -165,28 +163,28 @@ zpool_feature_init(void) { zfeature_register(SPA_FEATURE_ASYNC_DESTROY, "com.delphix:async_destroy", "async_destroy", - "Destroy filesystems asynchronously.", B_TRUE, B_FALSE, - B_FALSE, NULL); + "Destroy filesystems asynchronously.", + ZFEATURE_FLAG_READONLY_COMPAT, NULL); zfeature_register(SPA_FEATURE_EMPTY_BPOBJ, "com.delphix:empty_bpobj", "empty_bpobj", - "Snapshots use less space.", B_TRUE, B_FALSE, - B_FALSE, NULL); + "Snapshots use less space.", + ZFEATURE_FLAG_READONLY_COMPAT, NULL); zfeature_register(SPA_FEATURE_LZ4_COMPRESS, "org.illumos:lz4_compress", "lz4_compress", - "LZ4 compression algorithm support.", B_FALSE, B_FALSE, - B_TRUE, NULL); + "LZ4 compression algorithm support.", + ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, NULL); zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM, "com.delphix:spacemap_histogram", "spacemap_histogram", - "Spacemaps maintain space histograms.", B_TRUE, B_FALSE, - B_FALSE, NULL); + "Spacemaps maintain space histograms.", + ZFEATURE_FLAG_READONLY_COMPAT, NULL); zfeature_register(SPA_FEATURE_ENABLED_TXG, "com.delphix:enabled_txg", "enabled_txg", - "Record txg at which a feature is enabled", B_TRUE, B_FALSE, - B_FALSE, NULL); + "Record txg at which a feature is enabled", + ZFEATURE_FLAG_READONLY_COMPAT, NULL); { static const spa_feature_t hole_birth_deps[] = { @@ -196,13 +194,14 @@ zpool_feature_init(void) zfeature_register(SPA_FEATURE_HOLE_BIRTH, "com.delphix:hole_birth", "hole_birth", "Retain hole birth txg for more precise zfs send", - B_FALSE, B_TRUE, B_TRUE, hole_birth_deps); + ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, + hole_birth_deps); } zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET, "com.delphix:extensible_dataset", "extensible_dataset", "Enhanced dataset functionality, used by other features.", - B_FALSE, B_FALSE, B_FALSE, NULL); + 0, NULL); { static const spa_feature_t bookmarks_deps[] = { @@ -213,7 +212,7 @@ zpool_feature_init(void) zfeature_register(SPA_FEATURE_BOOKMARKS, "com.delphix:bookmarks", "bookmarks", "\"zfs bookmark\" command", - B_TRUE, B_FALSE, B_FALSE, bookmarks_deps); + ZFEATURE_FLAG_READONLY_COMPAT, bookmarks_deps); } { @@ -223,14 +222,15 @@ zpool_feature_init(void) }; zfeature_register(SPA_FEATURE_FS_SS_LIMIT, "com.joyent:filesystem_limits", "filesystem_limits", - "Filesystem and snapshot limits.", B_TRUE, B_FALSE, B_FALSE, - filesystem_limits_deps); + "Filesystem and snapshot limits.", + ZFEATURE_FLAG_READONLY_COMPAT, filesystem_limits_deps); } zfeature_register(SPA_FEATURE_EMBEDDED_DATA, "com.delphix:embedded_data", "embedded_data", "Blocks which compress very well use even less space.", - B_FALSE, B_TRUE, B_TRUE, NULL); + ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, + NULL); { static const spa_feature_t large_blocks_deps[] = { @@ -239,7 +239,7 @@ zpool_feature_init(void) }; zfeature_register(SPA_FEATURE_LARGE_BLOCKS, "org.open-zfs:large_blocks", "large_blocks", - "Support for blocks larger than 128KB.", B_FALSE, B_FALSE, B_FALSE, - large_blocks_deps); + "Support for blocks larger than 128KB.", + ZFEATURE_FLAG_PER_DATASET, large_blocks_deps); } } |