Date: Wed, 20 Nov 2013 10:54:06 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r258374 - vendor-sys/illumos/dist/common/zfs vendor-sys/illumos/dist/uts/common/fs/zfs vendor-sys/illumos/dist/uts/common/fs/zfs/sys vendor/illumos/dist/cmd/zdb vendor/illumos/dist/cmd/... Message-ID: <201311201054.rAKAs63j056222@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Wed Nov 20 10:54:06 2013 New Revision: 258374 URL: http://svnweb.freebsd.org/changeset/base/258374 Log: 4171 clean up spa_feature_*() interfaces 4172 implement extensible_dataset feature for use by other zpool features illumos/illumos-gate@2acef22db7808606888f8f92715629ff3ba555b9 Modified: vendor-sys/illumos/dist/common/zfs/zfeature_common.c vendor-sys/illumos/dist/common/zfs/zfeature_common.h vendor-sys/illumos/dist/uts/common/fs/zfs/bpobj.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_object.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_traverse.c vendor-sys/illumos/dist/uts/common/fs/zfs/dnode_sync.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_destroy.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dir.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_scan.c vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c vendor-sys/illumos/dist/uts/common/fs/zfs/space_map.c vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_impl.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dnode.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zap.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfeature.h vendor-sys/illumos/dist/uts/common/fs/zfs/zap_micro.c vendor-sys/illumos/dist/uts/common/fs/zfs/zfeature.c vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c Changes in other areas also in this revision: Modified: vendor/illumos/dist/cmd/zdb/zdb.c vendor/illumos/dist/cmd/zhack/zhack.c vendor/illumos/dist/cmd/zpool/zpool_main.c vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c vendor/illumos/dist/man/man5/zpool-features.5 Modified: vendor-sys/illumos/dist/common/zfs/zfeature_common.c ============================================================================== --- vendor-sys/illumos/dist/common/zfs/zfeature_common.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/common/zfs/zfeature_common.c Wed Nov 20 10:54:06 2013 (r258374) @@ -92,32 +92,22 @@ zfeature_is_supported(const char *guid) if (zfeature_checks_disable) return (B_TRUE); - return (0 == zfeature_lookup_guid(guid, NULL)); -} - -int -zfeature_lookup_guid(const char *guid, zfeature_info_t **res) -{ - for (int i = 0; i < SPA_FEATURES; i++) { + for (spa_feature_t i = 0; i < SPA_FEATURES; i++) { zfeature_info_t *feature = &spa_feature_table[i]; - if (strcmp(guid, feature->fi_guid) == 0) { - if (res != NULL) - *res = feature; - return (0); - } + if (strcmp(guid, feature->fi_guid) == 0) + return (B_TRUE); } - - return (ENOENT); + return (B_FALSE); } int -zfeature_lookup_name(const char *name, zfeature_info_t **res) +zfeature_lookup_name(const char *name, spa_feature_t *res) { - for (int i = 0; i < SPA_FEATURES; i++) { + for (spa_feature_t i = 0; i < SPA_FEATURES; i++) { zfeature_info_t *feature = &spa_feature_table[i]; if (strcmp(name, feature->fi_uname) == 0) { if (res != NULL) - *res = feature; + *res = i; return (0); } } @@ -126,11 +116,12 @@ zfeature_lookup_name(const char *name, z } static void -zfeature_register(int fid, const char *guid, const char *name, const char *desc, - boolean_t readonly, boolean_t mos, zfeature_info_t **deps) +zfeature_register(spa_feature_t fid, const char *guid, const char *name, + const char *desc, boolean_t readonly, boolean_t mos, + const spa_feature_t *deps) { zfeature_info_t *feature = &spa_feature_table[fid]; - static zfeature_info_t *nodeps[] = { NULL }; + static spa_feature_t nodeps[] = { SPA_FEATURE_NONE }; ASSERT(name != NULL); ASSERT(desc != NULL); @@ -141,6 +132,7 @@ zfeature_register(int fid, const char *g if (deps == NULL) deps = nodeps; + feature->fi_feature = fid; feature->fi_guid = guid; feature->fi_uname = name; feature->fi_desc = desc; @@ -167,4 +159,8 @@ zpool_feature_init(void) zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM, "com.delphix:spacemap_histogram", "spacemap_histogram", "Spacemaps maintain space histograms.", B_TRUE, B_FALSE, NULL); + zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET, + "com.delphix:extensible_dataset", "extensible_dataset", + "Enhanced dataset functionality, used by other features.", + B_FALSE, B_FALSE, NULL); } Modified: vendor-sys/illumos/dist/common/zfs/zfeature_common.h ============================================================================== --- vendor-sys/illumos/dist/common/zfs/zfeature_common.h Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/common/zfs/zfeature_common.h Wed Nov 20 10:54:06 2013 (r258374) @@ -38,35 +38,38 @@ extern "C" { struct zfeature_info; +typedef enum spa_feature { + SPA_FEATURE_NONE = -1, + SPA_FEATURE_ASYNC_DESTROY, + SPA_FEATURE_EMPTY_BPOBJ, + SPA_FEATURE_LZ4_COMPRESS, + SPA_FEATURE_MULTI_VDEV_CRASH_DUMP, + SPA_FEATURE_SPACEMAP_HISTOGRAM, + SPA_FEATURE_EXTENSIBLE_DATASET, + SPA_FEATURES +} spa_feature_t; + typedef struct zfeature_info { + spa_feature_t fi_feature; const char *fi_uname; /* User-facing feature name */ const char *fi_guid; /* On-disk feature identifier */ const char *fi_desc; /* Feature description */ boolean_t fi_can_readonly; /* Can open pool readonly w/o support? */ boolean_t fi_mos; /* Is the feature necessary to read the MOS? */ - struct zfeature_info **fi_depends; /* array; null terminated */ + /* array of dependencies, terminated by SPA_FEATURE_NONE */ + const spa_feature_t *fi_depends; } zfeature_info_t; typedef int (zfeature_func_t)(zfeature_info_t *fi, void *arg); #define ZFS_FEATURE_DEBUG -enum spa_feature { - SPA_FEATURE_ASYNC_DESTROY, - SPA_FEATURE_EMPTY_BPOBJ, - SPA_FEATURE_LZ4_COMPRESS, - SPA_FEATURE_MULTI_VDEV_CRASH_DUMP, - SPA_FEATURE_SPACEMAP_HISTOGRAM, - SPA_FEATURES -} spa_feature_t; - extern zfeature_info_t spa_feature_table[SPA_FEATURES]; extern boolean_t zfeature_is_valid_guid(const char *); extern boolean_t zfeature_is_supported(const char *); -extern int zfeature_lookup_guid(const char *, zfeature_info_t **res); -extern int zfeature_lookup_name(const char *, zfeature_info_t **res); +extern int zfeature_lookup_name(const char *name, spa_feature_t *res); extern void zpool_feature_init(void); Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/bpobj.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/bpobj.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/bpobj.c Wed Nov 20 10:54:06 2013 (r258374) @@ -36,13 +36,11 @@ uint64_t bpobj_alloc_empty(objset_t *os, int blocksize, dmu_tx_t *tx) { - zfeature_info_t *empty_bpobj_feat = - &spa_feature_table[SPA_FEATURE_EMPTY_BPOBJ]; spa_t *spa = dmu_objset_spa(os); dsl_pool_t *dp = dmu_objset_pool(os); - if (spa_feature_is_enabled(spa, empty_bpobj_feat)) { - if (!spa_feature_is_active(spa, empty_bpobj_feat)) { + if (spa_feature_is_enabled(spa, SPA_FEATURE_EMPTY_BPOBJ)) { + if (!spa_feature_is_active(spa, SPA_FEATURE_EMPTY_BPOBJ)) { ASSERT0(dp->dp_empty_bpobj); dp->dp_empty_bpobj = bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx); @@ -51,7 +49,7 @@ bpobj_alloc_empty(objset_t *os, int bloc DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1, &dp->dp_empty_bpobj, tx) == 0); } - spa_feature_incr(spa, empty_bpobj_feat, tx); + spa_feature_incr(spa, SPA_FEATURE_EMPTY_BPOBJ, tx); ASSERT(dp->dp_empty_bpobj != 0); return (dp->dp_empty_bpobj); } else { @@ -62,12 +60,11 @@ bpobj_alloc_empty(objset_t *os, int bloc void bpobj_decr_empty(objset_t *os, dmu_tx_t *tx) { - zfeature_info_t *empty_bpobj_feat = - &spa_feature_table[SPA_FEATURE_EMPTY_BPOBJ]; dsl_pool_t *dp = dmu_objset_pool(os); - spa_feature_decr(dmu_objset_spa(os), empty_bpobj_feat, tx); - if (!spa_feature_is_active(dmu_objset_spa(os), empty_bpobj_feat)) { + spa_feature_decr(dmu_objset_spa(os), SPA_FEATURE_EMPTY_BPOBJ, tx); + if (!spa_feature_is_active(dmu_objset_spa(os), + SPA_FEATURE_EMPTY_BPOBJ)) { VERIFY3U(0, ==, zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_EMPTY_BPOBJ, tx)); @@ -265,6 +262,7 @@ bpobj_iterate_impl(bpobj_t *bpo, bpobj_i mutex_exit(&bpo->bpo_lock); return (err); } + ASSERT3U(doi.doi_type, ==, DMU_OT_BPOBJ_SUBOBJ); epb = doi.doi_data_block_size / sizeof (uint64_t); for (i = bpo->bpo_phys->bpo_num_subobjs - 1; i >= 0; i--) { Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_object.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_object.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_object.c Wed Nov 20 10:54:06 2013 (r258374) @@ -27,6 +27,8 @@ #include <sys/dmu_objset.h> #include <sys/dmu_tx.h> #include <sys/dnode.h> +#include <sys/zap.h> +#include <sys/zfeature.h> uint64_t dmu_object_alloc(objset_t *os, dmu_object_type_t ot, int blocksize, @@ -195,3 +197,54 @@ dmu_object_next(objset_t *os, uint64_t * return (error); } + +/* + * Turn this object from old_type into DMU_OTN_ZAP_METADATA, and bump the + * refcount on SPA_FEATURE_EXTENSIBLE_DATASET. + * + * Only for use from syncing context, on MOS objects. + */ +void +dmu_object_zapify(objset_t *mos, uint64_t object, dmu_object_type_t old_type, + dmu_tx_t *tx) +{ + dnode_t *dn; + + ASSERT(dmu_tx_is_syncing(tx)); + + VERIFY0(dnode_hold(mos, object, FTAG, &dn)); + if (dn->dn_type == DMU_OTN_ZAP_METADATA) { + dnode_rele(dn, FTAG); + return; + } + ASSERT3U(dn->dn_type, ==, old_type); + ASSERT0(dn->dn_maxblkid); + dn->dn_next_type[tx->tx_txg & TXG_MASK] = dn->dn_type = + DMU_OTN_ZAP_METADATA; + dnode_setdirty(dn, tx); + dnode_rele(dn, FTAG); + + mzap_create_impl(mos, object, 0, 0, tx); + + spa_feature_incr(dmu_objset_spa(mos), + SPA_FEATURE_EXTENSIBLE_DATASET, tx); +} + +void +dmu_object_free_zapified(objset_t *mos, uint64_t object, dmu_tx_t *tx) +{ + dnode_t *dn; + dmu_object_type_t t; + + ASSERT(dmu_tx_is_syncing(tx)); + + VERIFY0(dnode_hold(mos, object, FTAG, &dn)); + t = dn->dn_type; + dnode_rele(dn, FTAG); + + if (t == DMU_OTN_ZAP_METADATA) { + spa_feature_decr(dmu_objset_spa(mos), + SPA_FEATURE_EXTENSIBLE_DATASET, tx); + } + VERIFY0(dmu_object_free(mos, object, tx)); +} Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_traverse.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_traverse.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_traverse.c Wed Nov 20 10:54:06 2013 (r258374) @@ -605,7 +605,7 @@ traverse_pool(spa_t *spa, uint64_t txg_s continue; } - if (doi.doi_type == DMU_OT_DSL_DATASET) { + if (doi.doi_bonus_type == DMU_OT_DSL_DATASET) { dsl_dataset_t *ds; uint64_t txg = txg_start; Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dnode_sync.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dnode_sync.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dnode_sync.c Wed Nov 20 10:54:06 2013 (r258374) @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include <sys/zfs_context.h> @@ -574,7 +574,12 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) BP_GET_LSIZE(&dnp->dn_blkptr[0]) == dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT); - if (dn->dn_next_blksz[txgoff]) { + if (dn->dn_next_type[txgoff] != 0) { + dnp->dn_type = dn->dn_type; + dn->dn_next_type[txgoff] = 0; + } + + if (dn->dn_next_blksz[txgoff] != 0) { ASSERT(P2PHASE(dn->dn_next_blksz[txgoff], SPA_MINBLOCKSIZE) == 0); ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[0]) || @@ -587,7 +592,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) dn->dn_next_blksz[txgoff] = 0; } - if (dn->dn_next_bonuslen[txgoff]) { + if (dn->dn_next_bonuslen[txgoff] != 0) { if (dn->dn_next_bonuslen[txgoff] == DN_ZERO_BONUSLEN) dnp->dn_bonuslen = 0; else @@ -596,7 +601,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) dn->dn_next_bonuslen[txgoff] = 0; } - if (dn->dn_next_bonustype[txgoff]) { + if (dn->dn_next_bonustype[txgoff] != 0) { ASSERT(DMU_OT_IS_VALID(dn->dn_next_bonustype[txgoff])); dnp->dn_bonustype = dn->dn_next_bonustype[txgoff]; dn->dn_next_bonustype[txgoff] = 0; @@ -614,7 +619,7 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) dn->dn_rm_spillblk[txgoff] = 0; } - if (dn->dn_next_indblkshift[txgoff]) { + if (dn->dn_next_indblkshift[txgoff] != 0) { ASSERT(dnp->dn_nlevels == 1); dnp->dn_indblkshift = dn->dn_next_indblkshift[txgoff]; dn->dn_next_indblkshift[txgoff] = 0; Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c Wed Nov 20 10:54:06 2013 (r258374) @@ -352,7 +352,7 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uin /* Make sure dsobj has the correct object type. */ dmu_object_info_from_db(dbuf, &doi); - if (doi.doi_type != DMU_OT_DSL_DATASET) { + if (doi.doi_bonus_type != DMU_OT_DSL_DATASET) { dmu_buf_rele(dbuf, tag); return (SET_ERROR(EINVAL)); } @@ -2972,3 +2972,11 @@ dsl_dataset_is_before(dsl_dataset_t *lat dsl_dataset_rele(origin, FTAG); return (ret); } + + +void +dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx) +{ + objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; + dmu_object_zapify(mos, ds->ds_object, DMU_OT_DSL_DATASET, tx); +} Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_destroy.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_destroy.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_destroy.c Wed Nov 20 10:54:06 2013 (r258374) @@ -38,6 +38,7 @@ #include <sys/zfeature.h> #include <sys/zfs_ioctl.h> #include <sys/dsl_deleg.h> +#include <sys/dmu_impl.h> typedef struct dmu_snapshots_destroy_arg { nvlist_t *dsda_snaps; @@ -448,7 +449,7 @@ dsl_destroy_snapshot_sync_impl(dsl_datas VERIFY0(zap_destroy(mos, ds->ds_phys->ds_userrefs_obj, tx)); dsl_dir_rele(ds->ds_dir, ds); ds->ds_dir = NULL; - VERIFY0(dmu_object_free(mos, obj, tx)); + dmu_object_free_zapified(mos, obj, tx); } static void @@ -671,7 +672,7 @@ dsl_dir_destroy_sync(uint64_t ddobj, dmu dd->dd_parent->dd_phys->dd_child_dir_zapobj, dd->dd_myname, tx)); dsl_dir_rele(dd, FTAG); - VERIFY0(dmu_object_free(mos, ddobj, tx)); + dmu_object_free_zapified(mos, ddobj, tx); } void @@ -724,10 +725,6 @@ dsl_destroy_head_sync_impl(dsl_dataset_t ds->ds_prev->ds_phys->ds_num_children--; } - zfeature_info_t *async_destroy = - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY]; - objset_t *os; - /* * Destroy the deadlist. Unless it's a clone, the * deadlist should be empty. (If it's a clone, it's @@ -738,9 +735,10 @@ dsl_destroy_head_sync_impl(dsl_dataset_t dmu_buf_will_dirty(ds->ds_dbuf, tx); ds->ds_phys->ds_deadlist_obj = 0; + objset_t *os; VERIFY0(dmu_objset_from_ds(ds, &os)); - if (!spa_feature_is_enabled(dp->dp_spa, async_destroy)) { + if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_ASYNC_DESTROY)) { old_synchronous_dataset_destroy(ds, tx); } else { /* @@ -751,10 +749,11 @@ dsl_destroy_head_sync_impl(dsl_dataset_t zil_destroy_sync(dmu_objset_zil(os), tx); - if (!spa_feature_is_active(dp->dp_spa, async_destroy)) { + if (!spa_feature_is_active(dp->dp_spa, + SPA_FEATURE_ASYNC_DESTROY)) { dsl_scan_t *scn = dp->dp_scan; - - spa_feature_incr(dp->dp_spa, async_destroy, tx); + spa_feature_incr(dp->dp_spa, SPA_FEATURE_ASYNC_DESTROY, + tx); dp->dp_bptree_obj = bptree_alloc(mos, tx); VERIFY0(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, @@ -814,7 +813,7 @@ dsl_destroy_head_sync_impl(dsl_dataset_t ASSERT0(ds->ds_phys->ds_userrefs_obj); dsl_dir_rele(ds->ds_dir, ds); ds->ds_dir = NULL; - VERIFY0(dmu_object_free(mos, obj, tx)); + dmu_object_free_zapified(mos, obj, tx); dsl_dir_destroy_sync(ddobj, tx); @@ -870,8 +869,7 @@ dsl_destroy_head(const char *name) error = spa_open(name, &spa, FTAG); if (error != 0) return (error); - isenabled = spa_feature_is_enabled(spa, - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY]); + isenabled = spa_feature_is_enabled(spa, SPA_FEATURE_ASYNC_DESTROY); spa_close(spa, FTAG); ddha.ddha_name = name; Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dir.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dir.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dir.c Wed Nov 20 10:54:06 2013 (r258374) @@ -32,6 +32,7 @@ #include <sys/dsl_prop.h> #include <sys/dsl_synctask.h> #include <sys/dsl_deleg.h> +#include <sys/dmu_impl.h> #include <sys/spa.h> #include <sys/metaslab.h> #include <sys/zap.h> @@ -88,7 +89,7 @@ dsl_dir_hold_obj(dsl_pool_t *dp, uint64_ { dmu_object_info_t doi; dmu_object_info_from_db(dbuf, &doi); - ASSERT3U(doi.doi_type, ==, DMU_OT_DSL_DIR); + ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_DSL_DIR); ASSERT3U(doi.doi_bonus_size, >=, sizeof (dsl_dir_phys_t)); } #endif @@ -1352,3 +1353,10 @@ dsl_dir_snap_cmtime_update(dsl_dir_t *dd dd->dd_snap_cmtime = t; mutex_exit(&dd->dd_lock); } + +void +dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx) +{ + objset_t *mos = dd->dd_pool->dp_meta_objset; + dmu_object_zapify(mos, dd->dd_object, DMU_OT_DSL_DIR, tx); +} Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c Wed Nov 20 10:54:06 2013 (r258374) @@ -250,8 +250,7 @@ dsl_pool_open(dsl_pool_t *dp) dp->dp_meta_objset, obj)); } - if (spa_feature_is_active(dp->dp_spa, - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { + if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_ASYNC_DESTROY)) { err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_BPTREE_OBJ, sizeof (uint64_t), 1, &dp->dp_bptree_obj); @@ -259,8 +258,7 @@ dsl_pool_open(dsl_pool_t *dp) goto out; } - if (spa_feature_is_active(dp->dp_spa, - &spa_feature_table[SPA_FEATURE_EMPTY_BPOBJ])) { + if (spa_feature_is_active(dp->dp_spa, SPA_FEATURE_EMPTY_BPOBJ)) { err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1, &dp->dp_empty_bpobj); Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_scan.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_scan.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_scan.c Wed Nov 20 10:54:06 2013 (r258374) @@ -102,7 +102,7 @@ dsl_scan_init(dsl_pool_t *dp, uint64_t t */ ASSERT(!scn->scn_async_destroying); scn->scn_async_destroying = spa_feature_is_active(dp->dp_spa, - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY]); + SPA_FEATURE_ASYNC_DESTROY); err = zap_lookup(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, "scrub_func", sizeof (uint64_t), 1, &f); @@ -1353,7 +1353,6 @@ dsl_scan_active(dsl_scan_t *scn) return (B_FALSE); if (spa_shutting_down(spa)) return (B_FALSE); - if (scn->scn_phys.scn_state == DSS_SCANNING || scn->scn_async_destroying) return (B_TRUE); @@ -1412,7 +1411,7 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t * VERIFY3U(0, ==, zio_wait(scn->scn_zio_root)); if (err == 0 && spa_feature_is_active(spa, - &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { + SPA_FEATURE_ASYNC_DESTROY)) { ASSERT(scn->scn_async_destroying); scn->scn_is_bptree = B_TRUE; scn->scn_zio_root = zio_root(dp->dp_spa, NULL, @@ -1423,11 +1422,11 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t * VERIFY0(zio_wait(scn->scn_zio_root)); if (err == 0) { - zfeature_info_t *feat = &spa_feature_table - [SPA_FEATURE_ASYNC_DESTROY]; /* finished; deactivate async destroy feature */ - spa_feature_decr(spa, feat, tx); - ASSERT(!spa_feature_is_active(spa, feat)); + spa_feature_decr(spa, SPA_FEATURE_ASYNC_DESTROY, + tx); + ASSERT(!spa_feature_is_active(spa, + SPA_FEATURE_ASYNC_DESTROY)); VERIFY0(zap_remove(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_BPTREE_OBJ, tx)); Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c Wed Nov 20 10:54:06 2013 (r258374) @@ -2300,14 +2300,12 @@ spa_load_impl(spa_t *spa, uint64_t pool_ enabled_feat = fnvlist_alloc(); unsup_feat = fnvlist_alloc(); - if (!feature_is_supported(spa->spa_meta_objset, - spa->spa_feat_for_read_obj, spa->spa_feat_desc_obj, + if (!spa_features_check(spa, B_FALSE, unsup_feat, enabled_feat)) missing_feat_read = B_TRUE; if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) { - if (!feature_is_supported(spa->spa_meta_objset, - spa->spa_feat_for_write_obj, spa->spa_feat_desc_obj, + if (!spa_features_check(spa, B_TRUE, unsup_feat, enabled_feat)) { missing_feat_write = B_TRUE; } @@ -5914,7 +5912,7 @@ spa_sync_props(void *arg, dmu_tx_t *tx) zpool_prop_t prop; const char *propname; zprop_type_t proptype; - zfeature_info_t *feature; + spa_feature_t fid; switch (prop = zpool_name_to_prop(nvpair_name(elem))) { case ZPROP_INVAL: @@ -5924,9 +5922,9 @@ spa_sync_props(void *arg, dmu_tx_t *tx) ASSERT(zpool_prop_feature(nvpair_name(elem))); fname = strchr(nvpair_name(elem), '@') + 1; - VERIFY0(zfeature_lookup_name(fname, &feature)); + VERIFY0(zfeature_lookup_name(fname, &fid)); - spa_feature_enable(spa, feature, tx); + spa_feature_enable(spa, fid, tx); spa_history_log_internal(spa, "set", tx, "%s=enabled", nvpair_name(elem)); break; Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c Wed Nov 20 10:54:06 2013 (r258374) @@ -1143,15 +1143,17 @@ spa_vdev_state_exit(spa_t *spa, vdev_t * void spa_activate_mos_feature(spa_t *spa, const char *feature) { - (void) nvlist_add_boolean(spa->spa_label_features, feature); - vdev_config_dirty(spa->spa_root_vdev); + if (!nvlist_exists(spa->spa_label_features, feature)) { + fnvlist_add_boolean(spa->spa_label_features, feature); + vdev_config_dirty(spa->spa_root_vdev); + } } void spa_deactivate_mos_feature(spa_t *spa, const char *feature) { - (void) nvlist_remove_all(spa->spa_label_features, feature); - vdev_config_dirty(spa->spa_root_vdev); + if (nvlist_remove_all(spa->spa_label_features, feature) == 0) + vdev_config_dirty(spa->spa_root_vdev); } /* Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/space_map.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/space_map.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/space_map.c Wed Nov 20 10:54:06 2013 (r258374) @@ -474,8 +474,6 @@ space_map_truncate(space_map_t *sm, dmu_ { objset_t *os = sm->sm_os; spa_t *spa = dmu_objset_spa(os); - zfeature_info_t *space_map_histogram = - &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM]; dmu_object_info_t doi; int bonuslen; @@ -485,7 +483,7 @@ space_map_truncate(space_map_t *sm, dmu_ VERIFY0(dmu_free_range(os, space_map_object(sm), 0, -1ULL, tx)); dmu_object_info_from_db(sm->sm_dbuf, &doi); - if (spa_feature_is_enabled(spa, space_map_histogram)) { + if (spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) { bonuslen = sizeof (space_map_phys_t); ASSERT3U(bonuslen, <=, dmu_bonus_max()); } else { @@ -525,13 +523,11 @@ uint64_t space_map_alloc(objset_t *os, dmu_tx_t *tx) { spa_t *spa = dmu_objset_spa(os); - zfeature_info_t *space_map_histogram = - &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM]; uint64_t object; int bonuslen; - if (spa_feature_is_enabled(spa, space_map_histogram)) { - spa_feature_incr(spa, space_map_histogram, tx); + if (spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) { + spa_feature_incr(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM, tx); bonuslen = sizeof (space_map_phys_t); ASSERT3U(bonuslen, <=, dmu_bonus_max()); } else { @@ -549,20 +545,20 @@ void space_map_free(space_map_t *sm, dmu_tx_t *tx) { spa_t *spa; - zfeature_info_t *space_map_histogram = - &spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM]; if (sm == NULL) return; spa = dmu_objset_spa(sm->sm_os); - if (spa_feature_is_enabled(spa, space_map_histogram)) { + if (spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) { dmu_object_info_t doi; dmu_object_info_from_db(sm->sm_dbuf, &doi); if (doi.doi_bonus_size != SPACE_MAP_SIZE_V0) { - VERIFY(spa_feature_is_active(spa, space_map_histogram)); - spa_feature_decr(spa, space_map_histogram, tx); + VERIFY(spa_feature_is_active(spa, + SPA_FEATURE_SPACEMAP_HISTOGRAM)); + spa_feature_decr(spa, + SPA_FEATURE_SPACEMAP_HISTOGRAM, tx); } } Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_impl.h ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_impl.h Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_impl.h Wed Nov 20 10:54:06 2013 (r258374) @@ -298,6 +298,8 @@ typedef struct dmu_sendarg { uint64_t dsa_last_data_offset; } dmu_sendarg_t; +void dmu_object_zapify(objset_t *, uint64_t, dmu_object_type_t, dmu_tx_t *); +void dmu_object_free_zapified(objset_t *, uint64_t, dmu_tx_t *); #ifdef __cplusplus } Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dnode.h ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dnode.h Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dnode.h Wed Nov 20 10:54:06 2013 (r258374) @@ -178,6 +178,7 @@ typedef struct dnode { uint16_t dn_datablkszsec; /* in 512b sectors */ uint32_t dn_datablksz; /* in bytes */ uint64_t dn_maxblkid; + uint8_t dn_next_type[TXG_SIZE]; uint8_t dn_next_nblkptr[TXG_SIZE]; uint8_t dn_next_nlevels[TXG_SIZE]; uint8_t dn_next_indblkshift[TXG_SIZE]; Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h Wed Nov 20 10:54:06 2013 (r258374) @@ -49,9 +49,9 @@ struct dsl_pool; #define DS_FLAG_INCONSISTENT (1ULL<<0) #define DS_IS_INCONSISTENT(ds) \ ((ds)->ds_phys->ds_flags & DS_FLAG_INCONSISTENT) + /* - * Note: nopromote can not yet be set, but we want support for it in this - * on-disk version, so that we don't need to upgrade for it later. + * Do not allow this dataset to be promoted. */ #define DS_FLAG_NOPROMOTE (1ULL<<1) @@ -71,6 +71,11 @@ struct dsl_pool; ((ds)->ds_phys->ds_flags & DS_FLAG_DEFER_DESTROY) /* + * DS_FIELD_* are strings that are used in the "extensified" dataset zap object. + * They should be of the format <reverse-dns>:<field>. + */ + +/* * DS_FLAG_CI_DATASET is set if the dataset contains a file system whose * name lookups should be performed case-insensitively. */ Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zap.h ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zap.h Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zap.h Wed Nov 20 10:54:06 2013 (r258374) @@ -141,6 +141,12 @@ uint64_t zap_create_link(objset_t *os, d uint64_t parent_obj, const char *name, dmu_tx_t *tx); /* + * Initialize an already-allocated object. + */ +void mzap_create_impl(objset_t *os, uint64_t obj, int normflags, + zap_flags_t flags, dmu_tx_t *tx); + +/* * Create a new zapobj with no attributes from the given (unallocated) * object number. */ Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfeature.h ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfeature.h Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfeature.h Wed Nov 20 10:54:06 2013 (r258374) @@ -27,6 +27,7 @@ #define _SYS_ZFEATURE_H #include <sys/nvpair.h> +#include <sys/txg.h> #include "zfeature_common.h" #ifdef __cplusplus @@ -37,17 +38,25 @@ struct spa; struct dmu_tx; struct objset; -extern boolean_t feature_is_supported(struct objset *os, uint64_t obj, - uint64_t desc_obj, nvlist_t *unsup_feat, nvlist_t *enabled_feat); - extern void spa_feature_create_zap_objects(struct spa *, struct dmu_tx *); -extern void spa_feature_enable(struct spa *, zfeature_info_t *, +extern void spa_feature_enable(struct spa *, spa_feature_t, + struct dmu_tx *); +extern void spa_feature_incr(struct spa *, spa_feature_t, struct dmu_tx *); +extern void spa_feature_decr(struct spa *, spa_feature_t, struct dmu_tx *); +extern boolean_t spa_feature_is_enabled(struct spa *, spa_feature_t); +extern boolean_t spa_feature_is_active(struct spa *, spa_feature_t); +extern uint64_t spa_feature_refcount(spa_t *, spa_feature_t, uint64_t); +extern boolean_t spa_features_check(spa_t *, boolean_t, nvlist_t *, nvlist_t *); + +/* + * These functions are only exported for zhack and zdb; normal callers should + * use the above interfaces. + */ +extern int feature_get_refcount(struct spa *, zfeature_info_t *, uint64_t *); +extern void feature_enable_sync(struct spa *, zfeature_info_t *, + struct dmu_tx *); +extern void feature_sync(struct spa *, zfeature_info_t *, uint64_t, struct dmu_tx *); -extern void spa_feature_incr(struct spa *, zfeature_info_t *, struct dmu_tx *); -extern void spa_feature_decr(struct spa *, zfeature_info_t *, struct dmu_tx *); -extern boolean_t spa_feature_is_enabled(struct spa *, zfeature_info_t *); -extern boolean_t spa_feature_is_active(struct spa *, zfeature_info_t *); -extern int spa_feature_get_refcount(struct spa *, zfeature_info_t *); #ifdef __cplusplus } Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zap_micro.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/zap_micro.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/zap_micro.c Wed Nov 20 10:54:06 2013 (r258374) @@ -572,7 +572,7 @@ mzap_upgrade(zap_t **zapp, dmu_tx_t *tx, return (err); } -static void +void mzap_create_impl(objset_t *os, uint64_t obj, int normflags, zap_flags_t flags, dmu_tx_t *tx) { @@ -862,8 +862,8 @@ zap_lookup_uint64(objset_t *os, uint64_t int zap_contains(objset_t *os, uint64_t zapobj, const char *name) { - int err = (zap_lookup_norm(os, zapobj, name, 0, - 0, NULL, MT_EXACT, NULL, 0, NULL)); + int err = zap_lookup_norm(os, zapobj, name, 0, + 0, NULL, MT_EXACT, NULL, 0, NULL); if (err == EOVERFLOW || err == EINVAL) err = 0; /* found, but skipped reading the value */ return (err); Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zfeature.c ============================================================================== --- vendor-sys/illumos/dist/uts/common/fs/zfs/zfeature.c Wed Nov 20 10:52:48 2013 (r258373) +++ vendor-sys/illumos/dist/uts/common/fs/zfs/zfeature.c Wed Nov 20 10:54:06 2013 (r258374) @@ -161,23 +161,25 @@ */ typedef enum { - FEATURE_ACTION_ENABLE, FEATURE_ACTION_INCR, FEATURE_ACTION_DECR, } feature_action_t; /* - * Checks that the features active in the specified object are supported by + * Checks that the active features in the pool are supported by * this software. Adds each unsupported feature (name -> description) to * the supplied nvlist. */ boolean_t -feature_is_supported(objset_t *os, uint64_t obj, uint64_t desc_obj, +spa_features_check(spa_t *spa, boolean_t for_write, nvlist_t *unsup_feat, nvlist_t *enabled_feat) { + objset_t *os = spa->spa_meta_objset; boolean_t supported; zap_cursor_t zc; zap_attribute_t za; + uint64_t obj = for_write ? + spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; supported = B_TRUE; for (zap_cursor_init(&zc, os, obj); @@ -199,8 +201,8 @@ feature_is_supported(objset_t *os, uint6 char *desc = ""; char buf[MAXPATHLEN]; - if (zap_lookup(os, desc_obj, za.za_name, - 1, sizeof (buf), buf) == 0) + if (zap_lookup(os, spa->spa_feat_desc_obj, + za.za_name, 1, sizeof (buf), buf) == 0) desc = buf; VERIFY(nvlist_add_string(unsup_feat, za.za_name, @@ -213,13 +215,18 @@ feature_is_supported(objset_t *os, uint6 return (supported); } -static int -feature_get_refcount(objset_t *os, uint64_t read_obj, uint64_t write_obj, - zfeature_info_t *feature, uint64_t *res) +/* + * Note: well-designed features will not need to use this; they should + * use spa_feature_is_enabled() and spa_feature_is_active() instead. + * However, this is non-static for zdb and zhack. + */ +int +feature_get_refcount(spa_t *spa, zfeature_info_t *feature, uint64_t *res) { int err; uint64_t refcount; - uint64_t zapobj = feature->fi_can_readonly ? write_obj : read_obj; + uint64_t zapobj = feature->fi_can_readonly ? + spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; /* * If the pool is currently being created, the feature objects may not @@ -228,8 +235,8 @@ feature_get_refcount(objset_t *os, uint6 if (zapobj == 0) return (SET_ERROR(ENOTSUP)); - err = zap_lookup(os, zapobj, feature->fi_guid, sizeof (uint64_t), 1, - &refcount); + err = zap_lookup(spa->spa_meta_objset, zapobj, + feature->fi_guid, sizeof (uint64_t), 1, &refcount); if (err != 0) { if (err == ENOENT) return (SET_ERROR(ENOTSUP)); @@ -240,49 +247,81 @@ feature_get_refcount(objset_t *os, uint6 return (0); } -static int -feature_do_action(objset_t *os, uint64_t read_obj, uint64_t write_obj, - uint64_t desc_obj, zfeature_info_t *feature, feature_action_t action, +/* + * This function is non-static for zhack; it should otherwise not be used + * outside this file. + */ +void +feature_sync(spa_t *spa, zfeature_info_t *feature, uint64_t refcount, dmu_tx_t *tx) { - int error; - uint64_t refcount; - uint64_t zapobj = feature->fi_can_readonly ? write_obj : read_obj; + uint64_t zapobj = feature->fi_can_readonly ? + 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)); + + if (refcount == 0) + spa_deactivate_mos_feature(spa, feature->fi_guid); + else if (feature->fi_mos) + spa_activate_mos_feature(spa, feature->fi_guid); +} + +/* + * This function is non-static for zhack; it should otherwise not be used + * outside this file. + */ +void +feature_enable_sync(spa_t *spa, zfeature_info_t *feature, dmu_tx_t *tx) +{ + uint64_t zapobj = feature->fi_can_readonly ? + spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; ASSERT(0 != zapobj); ASSERT(zfeature_is_valid_guid(feature->fi_guid)); - - error = zap_lookup(os, zapobj, feature->fi_guid, - sizeof (uint64_t), 1, &refcount); + ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES); /* - * If we can't ascertain the status of the specified feature, an I/O - * error occurred. + * If the feature is already enabled, ignore the request. */ - if (error != 0 && error != ENOENT) - return (error); + if (zap_contains(spa->spa_meta_objset, zapobj, feature->fi_guid) == 0) + return; + + for (int i = 0; feature->fi_depends[i] != SPA_FEATURE_NONE; i++) + spa_feature_enable(spa, feature->fi_depends[i], tx); + + VERIFY0(zap_update(spa->spa_meta_objset, spa->spa_feat_desc_obj, + feature->fi_guid, 1, strlen(feature->fi_desc) + 1, + feature->fi_desc, tx)); + feature_sync(spa, feature, 0, tx); +} + +static void +feature_do_action(spa_t *spa, spa_feature_t fid, feature_action_t action, + dmu_tx_t *tx) +{ + uint64_t refcount; + zfeature_info_t *feature = &spa_feature_table[fid]; + uint64_t zapobj = feature->fi_can_readonly ? + spa->spa_feat_for_write_obj : spa->spa_feat_for_read_obj; + + ASSERT3U(fid, <, SPA_FEATURES); + ASSERT(0 != zapobj); + ASSERT(zfeature_is_valid_guid(feature->fi_guid)); + + ASSERT(dmu_tx_is_syncing(tx)); + ASSERT3U(spa_version(spa), >=, SPA_VERSION_FEATURES); + + VERIFY0(zap_lookup(spa->spa_meta_objset, zapobj, feature->fi_guid, + sizeof (uint64_t), 1, &refcount)); switch (action) { - case FEATURE_ACTION_ENABLE: - /* - * If the feature is already enabled, ignore the request. - */ - if (error == 0) - return (0); - refcount = 0; - break; case FEATURE_ACTION_INCR: - if (error == ENOENT) - return (SET_ERROR(ENOTSUP)); - if (refcount == UINT64_MAX) - return (SET_ERROR(EOVERFLOW)); + VERIFY3U(refcount, !=, UINT64_MAX); refcount++; break; case FEATURE_ACTION_DECR: - if (error == ENOENT) - return (SET_ERROR(ENOTSUP)); - if (refcount == 0) - return (SET_ERROR(EOVERFLOW)); + VERIFY3U(refcount, !=, 0); refcount--; break; default: @@ -290,42 +329,7 @@ feature_do_action(objset_t *os, uint64_t break; } - if (action == FEATURE_ACTION_ENABLE) { - int i; - - for (i = 0; feature->fi_depends[i] != NULL; i++) { - zfeature_info_t *dep = feature->fi_depends[i]; - - error = feature_do_action(os, read_obj, write_obj, - desc_obj, dep, FEATURE_ACTION_ENABLE, tx); - if (error != 0) - return (error); - } - } - - error = zap_update(os, zapobj, feature->fi_guid, - sizeof (uint64_t), 1, &refcount, tx); - if (error != 0) - return (error); - - if (action == FEATURE_ACTION_ENABLE) { - error = zap_update(os, desc_obj, - feature->fi_guid, 1, strlen(feature->fi_desc) + 1, - feature->fi_desc, tx); - if (error != 0) - return (error); - } - - if (action == FEATURE_ACTION_INCR && refcount == 1 && feature->fi_mos) { - spa_activate_mos_feature(dmu_objset_spa(os), feature->fi_guid); - } - - if (action == FEATURE_ACTION_DECR && refcount == 0) { - spa_deactivate_mos_feature(dmu_objset_spa(os), - feature->fi_guid); - } - - return (0); + feature_sync(spa, feature, refcount, tx); } void @@ -353,82 +357,51 @@ spa_feature_create_zap_objects(spa_t *sp * Enable any required dependencies, then enable the requested feature. *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311201054.rAKAs63j056222>