spa.c revision e0f1c0afa46cc84d4b1e40124032a9a87310386e
1fa9e406ahrens/*
2fa9e406ahrens * CDDL HEADER START
3fa9e406ahrens *
4fa9e406ahrens * The contents of this file are subject to the terms of the
5ea8dc4beschrock * Common Development and Distribution License (the "License").
6ea8dc4beschrock * You may not use this file except in compliance with the License.
7fa9e406ahrens *
8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e406ahrens * or http://www.opensolaris.org/os/licensing.
10fa9e406ahrens * See the License for the specific language governing permissions
11fa9e406ahrens * and limitations under the License.
12fa9e406ahrens *
13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each
14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the
16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e406ahrens *
19fa9e406ahrens * CDDL HEADER END
20fa9e406ahrens */
2199653d4eschrock
22fa9e406ahrens/*
2398d1cbfGeorge Wilson * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
245cabbc6Prashanth Sreenivasa * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
251437283Hans Rosenfeld * Copyright (c) 2015, Nexenta Systems, Inc.  All rights reserved.
26bc9014eJustin Gibbs * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
2745818eeMatthew Ahrens * Copyright 2013 Saso Kiselkov. All rights reserved.
28c3d26abMatthew Ahrens * Copyright (c) 2014 Integros [integros.com]
29c8811bdToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com>
3082f63c3Jerry Jelinek * Copyright 2018 Joyent, Inc.
311702cceAlek Pinchuk * Copyright (c) 2017 Datto Inc.
320fb055eAndy Fiddaman * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
335aeb947Garrett D'Amore */
34fa9e406ahrens
35fa9e406ahrens/*
363e30c24Will Andrews * SPA: Storage Pool Allocator
373e30c24Will Andrews *
38fa9e406ahrens * This file contains all the routines used when modifying on-disk SPA state.
39fa9e406ahrens * This includes opening, importing, destroying, exporting a pool, and syncing a
40fa9e406ahrens * pool.
41fa9e406ahrens */
42fa9e406ahrens
43fa9e406ahrens#include <sys/zfs_context.h>
44ea8dc4beschrock#include <sys/fm/fs/zfs.h>
45fa9e406ahrens#include <sys/spa_impl.h>
46fa9e406ahrens#include <sys/zio.h>
47fa9e406ahrens#include <sys/zio_checksum.h>
48fa9e406ahrens#include <sys/dmu.h>
49fa9e406ahrens#include <sys/dmu_tx.h>
50fa9e406ahrens#include <sys/zap.h>
51fa9e406ahrens#include <sys/zil.h>
52b24ab67Jeff Bonwick#include <sys/ddt.h>
53fa9e406ahrens#include <sys/vdev_impl.h>
545cabbc6Prashanth Sreenivasa#include <sys/vdev_removal.h>
555cabbc6Prashanth Sreenivasa#include <sys/vdev_indirect_mapping.h>
565cabbc6Prashanth Sreenivasa#include <sys/vdev_indirect_births.h>
57094e47eGeorge Wilson#include <sys/vdev_initialize.h>
58fa9e406ahrens#include <sys/metaslab.h>
5988ecc94George Wilson#include <sys/metaslab_impl.h>
60e0f1c0aOlaf Faaland#include <sys/mmp.h>
61fa9e406ahrens#include <sys/uberblock_impl.h>
62fa9e406ahrens#include <sys/txg.h>
63fa9e406ahrens#include <sys/avl.h>
645cabbc6Prashanth Sreenivasa#include <sys/bpobj.h>
65fa9e406ahrens#include <sys/dmu_traverse.h>
66b1b8ab3lling#include <sys/dmu_objset.h>
67fa9e406ahrens#include <sys/unique.h>
68fa9e406ahrens#include <sys/dsl_pool.h>
69b1b8ab3lling#include <sys/dsl_dataset.h>
70fa9e406ahrens#include <sys/dsl_dir.h>
71fa9e406ahrens#include <sys/dsl_prop.h>
72b1b8ab3lling#include <sys/dsl_synctask.h>
73fa9e406ahrens#include <sys/fs/zfs.h>
74fa94a07brendan#include <sys/arc.h>
75fa9e406ahrens#include <sys/callb.h>
769517395ek#include <sys/systeminfo.h>
77e7cbe64gw#include <sys/spa_boot.h>
78573ca77George Wilson#include <sys/zfs_ioctl.h>
793f9d6adLin Ling#include <sys/dsl_scan.h>
80ad135b5Christopher Siden#include <sys/zfeature.h>
813b2aab1Matthew Ahrens#include <sys/dsl_destroy.h>
82770499eDan Kimmel#include <sys/abd.h>
83fa9e406ahrens
845679c89jv#ifdef	_KERNEL
85dedec47Jack Meng#include <sys/bootprops.h>
8635a5a35Jonathan Adams#include <sys/callb.h>
8735a5a35Jonathan Adams#include <sys/cpupart.h>
8835a5a35Jonathan Adams#include <sys/pool.h>
8935a5a35Jonathan Adams#include <sys/sysdc.h>
9035a5a35Jonathan Adams#include <sys/zone.h>
915679c89jv#endif	/* _KERNEL */
925679c89jv
93990b485lling#include "zfs_prop.h"
94b7b9745perrin#include "zfs_comutil.h"
95990b485lling
963cb69f7Will Andrews/*
973cb69f7Will Andrews * The interval, in seconds, at which failed configuration cache file writes
983cb69f7Will Andrews * should be retried.
993cb69f7Will Andrews */
1005cabbc6Prashanth Sreenivasaint zfs_ccw_retry_interval = 300;
1013cb69f7Will Andrews
10235a5a35Jonathan Adamstypedef enum zti_modes {
103ec94d32Adam Leventhal	ZTI_MODE_FIXED,			/* value is # of threads (min 1) */
104ec94d32Adam Leventhal	ZTI_MODE_BATCH,			/* cpu-intensive; value is ignored */
105ec94d32Adam Leventhal	ZTI_MODE_NULL,			/* don't create a taskq */
106ec94d32Adam Leventhal	ZTI_NMODES
10735a5a35Jonathan Adams} zti_modes_t;
108416e0cdek
109ec94d32Adam Leventhal#define	ZTI_P(n, q)	{ ZTI_MODE_FIXED, (n), (q) }
110ec94d32Adam Leventhal#define	ZTI_BATCH	{ ZTI_MODE_BATCH, 0, 1 }
111ec94d32Adam Leventhal#define	ZTI_NULL	{ ZTI_MODE_NULL, 0, 0 }
1122e0c549Jonathan Adams
113ec94d32Adam Leventhal#define	ZTI_N(n)	ZTI_P(n, 1)
114ec94d32Adam Leventhal#define	ZTI_ONE		ZTI_N(1)
1152e0c549Jonathan Adams
1162e0c549Jonathan Adamstypedef struct zio_taskq_info {
117ec94d32Adam Leventhal	zti_modes_t zti_mode;
11880eb36fGeorge Wilson	uint_t zti_value;
119ec94d32Adam Leventhal	uint_t zti_count;
1202e0c549Jonathan Adams} zio_taskq_info_t;
1212e0c549Jonathan Adams
1222e0c549Jonathan Adamsstatic const char *const zio_taskq_types[ZIO_TASKQ_TYPES] = {
12335a5a35Jonathan Adams	"issue", "issue_high", "intr", "intr_high"
1242e0c549Jonathan Adams};
1252e0c549Jonathan Adams
12680eb36fGeorge Wilson/*
127ec94d32Adam Leventhal * This table defines the taskq settings for each ZFS I/O type. When
128ec94d32Adam Leventhal * initializing a pool, we use this table to create an appropriately sized
129ec94d32Adam Leventhal * taskq. Some operations are low volume and therefore have a small, static
130ec94d32Adam Leventhal * number of threads assigned to their taskqs using the ZTI_N(#) or ZTI_ONE
131ec94d32Adam Leventhal * macros. Other operations process a large amount of data; the ZTI_BATCH
132ec94d32Adam Leventhal * macro causes us to create a taskq oriented for throughput. Some operations
133ec94d32Adam Leventhal * are so high frequency and short-lived that the taskq itself can become a a
134ec94d32Adam Leventhal * point of lock contention. The ZTI_P(#, #) macro indicates that we need an
135ec94d32Adam Leventhal * additional degree of parallelism specified by the number of threads per-
136ec94d32Adam Leventhal * taskq and the number of taskqs; when dispatching an event in this case, the
137ec94d32Adam Leventhal * particular taskq is chosen at random.
138ec94d32Adam Leventhal *
139ec94d32Adam Leventhal * The different taskq priorities are to handle the different contexts (issue
140ec94d32Adam Leventhal * and interrupt) and then to reserve threads for ZIO_PRIORITY_NOW I/Os that
141ec94d32Adam Leventhal * need to be handled with minimum delay.
14280eb36fGeorge Wilson */
14380eb36fGeorge Wilsonconst zio_taskq_info_t zio_taskqs[ZIO_TYPES][ZIO_TASKQ_TYPES] = {
14480eb36fGeorge Wilson	/* ISSUE	ISSUE_HIGH	INTR		INTR_HIGH */
145ec94d32Adam Leventhal	{ ZTI_ONE,	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* NULL */
1461b497abAdam H. Leventhal	{ ZTI_N(8),	ZTI_NULL,	ZTI_P(12, 8),	ZTI_NULL }, /* READ */
147ec94d32Adam Leventhal	{ ZTI_BATCH,	ZTI_N(5),	ZTI_N(8),	ZTI_N(5) }, /* WRITE */
148ec94d32Adam Leventhal	{ ZTI_P(12, 8),	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* FREE */
149ec94d32Adam Leventhal	{ ZTI_ONE,	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* CLAIM */
150ec94d32Adam Leventhal	{ ZTI_ONE,	ZTI_NULL,	ZTI_ONE,	ZTI_NULL }, /* IOCTL */
1512e0c549Jonathan Adams};
1522e0c549Jonathan Adams
1533b2aab1Matthew Ahrensstatic void spa_sync_version(void *arg, dmu_tx_t *tx);
1543b2aab1Matthew Ahrensstatic void spa_sync_props(void *arg, dmu_tx_t *tx);
15589a89ebllingstatic boolean_t spa_has_active_shared_spare(spa_t *spa);
1568671400Serapheim Dimitropoulosstatic int spa_load_impl(spa_t *spa, spa_import_type_t type, char **ereport);
157cb04b87Mark J Musantestatic void spa_vdev_resilver_done(spa_t *spa);
158990b485lling
15969962b5Matthew Ahrensuint_t		zio_taskq_batch_pct = 75;	/* 1 thread per cpu in pset */
16035a5a35Jonathan Adamsid_t		zio_taskq_psrset_bind = PS_NONE;
16135a5a35Jonathan Adamsboolean_t	zio_taskq_sysdc = B_TRUE;	/* use SDC scheduling class */
16235a5a35Jonathan Adamsuint_t		zio_taskq_basedc = 80;		/* base duty cycle */
16335a5a35Jonathan Adams
16435a5a35Jonathan Adamsboolean_t	spa_create_process = B_TRUE;	/* no process ==> no sysdc */
16501f55e4George Wilsonextern int	zfs_sync_pass_deferred_free;
16635a5a35Jonathan Adams
16735a5a35Jonathan Adams/*
168e144c4ePavel Zakharov * Report any spa_load_verify errors found, but do not fail spa_load.
169e144c4ePavel Zakharov * This is used by zdb to analyze non-idle pools.
170e144c4ePavel Zakharov */
171e144c4ePavel Zakharovboolean_t	spa_load_verify_dryrun = B_FALSE;
172e144c4ePavel Zakharov
173e144c4ePavel Zakharov/*
17435a5a35Jonathan Adams * This (illegal) pool name is used when temporarily importing a spa_t in order
17535a5a35Jonathan Adams * to get the vdev stats associated with the imported devices.
17635a5a35Jonathan Adams */
17735a5a35Jonathan Adams#define	TRYIMPORT_NAME	"$import"
17835a5a35Jonathan Adams
179990b485lling/*
1806f79381Pavel Zakharov * For debugging purposes: print out vdev tree during pool import.
1816f79381Pavel Zakharov */
1826f79381Pavel Zakharovboolean_t	spa_load_print_vdev_tree = B_FALSE;
1836f79381Pavel Zakharov
1846f79381Pavel Zakharov/*
1856f79381Pavel Zakharov * A non-zero value for zfs_max_missing_tvds means that we allow importing
1866f79381Pavel Zakharov * pools with missing top-level vdevs. This is strictly intended for advanced
1876f79381Pavel Zakharov * pool recovery cases since missing data is almost inevitable. Pools with
1886f79381Pavel Zakharov * missing devices can only be imported read-only for safety reasons, and their
1896f79381Pavel Zakharov * fail-mode will be automatically set to "continue".
1906f79381Pavel Zakharov *
1916f79381Pavel Zakharov * With 1 missing vdev we should be able to import the pool and mount all
1926f79381Pavel Zakharov * datasets. User data that was not modified after the missing device has been
1936f79381Pavel Zakharov * added should be recoverable. This means that snapshots created prior to the
1946f79381Pavel Zakharov * addition of that device should be completely intact.
1956f79381Pavel Zakharov *
1966f79381Pavel Zakharov * With 2 missing vdevs, some datasets may fail to mount since there are
1976f79381Pavel Zakharov * dataset statistics that are stored as regular metadata. Some data might be
1986f79381Pavel Zakharov * recoverable if those vdevs were added recently.
1996f79381Pavel Zakharov *
2006f79381Pavel Zakharov * With 3 or more missing vdevs, the pool is severely damaged and MOS entries
2016f79381Pavel Zakharov * may be missing entirely. Chances of data recovery are very low. Note that
2026f79381Pavel Zakharov * there are also risks of performing an inadvertent rewind as we might be
2036f79381Pavel Zakharov * missing all the vdevs with the latest uberblocks.
2046f79381Pavel Zakharov */
2056f79381Pavel Zakharovuint64_t	zfs_max_missing_tvds = 0;
2066f79381Pavel Zakharov
2076f79381Pavel Zakharov/*
2086f79381Pavel Zakharov * The parameters below are similar to zfs_max_missing_tvds but are only
2096f79381Pavel Zakharov * intended for a preliminary open of the pool with an untrusted config which
2106f79381Pavel Zakharov * might be incomplete or out-dated.
2116f79381Pavel Zakharov *
2126f79381Pavel Zakharov * We are more tolerant for pools opened from a cachefile since we could have
2136f79381Pavel Zakharov * an out-dated cachefile where a device removal was not registered.
2146f79381Pavel Zakharov * We could have set the limit arbitrarily high but in the case where devices
2156f79381Pavel Zakharov * are really missing we would want to return the proper error codes; we chose
2166f79381Pavel Zakharov * SPA_DVAS_PER_BP - 1 so that some copies of the MOS would still be available
2176f79381Pavel Zakharov * and we get a chance to retrieve the trusted config.
2186f79381Pavel Zakharov */
2196f79381Pavel Zakharovuint64_t	zfs_max_missing_tvds_cachefile = SPA_DVAS_PER_BP - 1;
2208671400Serapheim Dimitropoulos
2216f79381Pavel Zakharov/*
2226f79381Pavel Zakharov * In the case where config was assembled by scanning device paths (/dev/dsks
2236f79381Pavel Zakharov * by default) we are less tolerant since all the existing devices should have
2246f79381Pavel Zakharov * been detected and we want spa_load to return the right error codes.
2256f79381Pavel Zakharov */
2266f79381Pavel Zakharovuint64_t	zfs_max_missing_tvds_scan = 0;
2276f79381Pavel Zakharov
2286f79381Pavel Zakharov/*
2298671400Serapheim Dimitropoulos * Debugging aid that pauses spa_sync() towards the end.
2308671400Serapheim Dimitropoulos */
2318671400Serapheim Dimitropoulosboolean_t	zfs_pause_spa_sync = B_FALSE;
2328671400Serapheim Dimitropoulos
2338671400Serapheim Dimitropoulos/*
234990b485lling * ==========================================================================
235990b485lling * SPA properties routines
236990b485lling * ==========================================================================
237990b485lling */
238990b485lling
239990b485lling/*
240990b485lling * Add a (source=src, propname=propval) list to an nvlist.
241990b485lling */
2429d82f4fllingstatic void
243990b485llingspa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval,
244990b485lling    uint64_t intval, zprop_source_t src)
245990b485lling{
246990b485lling	const char *propname = zpool_prop_to_name(prop);
247990b485lling	nvlist_t *propval;
248990b485lling
2499d82f4flling	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2509d82f4flling	VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0);
251990b485lling
2529d82f4flling	if (strval != NULL)
2539d82f4flling		VERIFY(nvlist_add_string(propval, ZPROP_VALUE, strval) == 0);
2549d82f4flling	else
2559d82f4flling		VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, intval) == 0);
256990b485lling
2579d82f4flling	VERIFY(nvlist_add_nvlist(nvl, propname, propval) == 0);
258990b485lling	nvlist_free(propval);
259990b485lling}
260990b485lling
261990b485lling/*
262990b485lling * Get property values from the spa configuration.
263990b485lling */
2649d82f4fllingstatic void
265990b485llingspa_prop_get_config(spa_t *spa, nvlist_t **nvp)
266990b485lling{
2674263d13George Wilson	vdev_t *rvd = spa->spa_root_vdev;
268ad135b5Christopher Siden	dsl_pool_t *pool = spa->spa_dsl_pool;
2692e4c998George Wilson	uint64_t size, alloc, cap, version;
270990b485lling	zprop_source_t src = ZPROP_SRC_NONE;
271c5904d1eschrock	spa_config_dirent_t *dp;
2722e4c998George Wilson	metaslab_class_t *mc = spa_normal_class(spa);
273990b485lling
274e14bb32Jeff Bonwick	ASSERT(MUTEX_HELD(&spa->spa_props_lock));
275e14bb32Jeff Bonwick
2764263d13George Wilson	if (rvd != NULL) {
277485bbbfGeorge Wilson		alloc = metaslab_class_get_alloc(spa_normal_class(spa));
278b24ab67Jeff Bonwick		size = metaslab_class_get_space(spa_normal_class(spa));
279379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src);
280379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src);
281485bbbfGeorge Wilson		spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src);
282485bbbfGeorge Wilson		spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL,
283485bbbfGeorge Wilson		    size - alloc, src);
2848671400Serapheim Dimitropoulos		spa_prop_add_list(*nvp, ZPOOL_PROP_CHECKPOINT, NULL,
2858671400Serapheim Dimitropoulos		    spa->spa_checkpoint_info.sci_dspace, src);
2864263d13George Wilson
2872e4c998George Wilson		spa_prop_add_list(*nvp, ZPOOL_PROP_FRAGMENTATION, NULL,
2882e4c998George Wilson		    metaslab_class_fragmentation(mc), src);
2892e4c998George Wilson		spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL,
2902e4c998George Wilson		    metaslab_class_expandable_space(mc), src);
291f9af39bGeorge Wilson		spa_prop_add_list(*nvp, ZPOOL_PROP_READONLY, NULL,
292f9af39bGeorge Wilson		    (spa_mode(spa) == FREAD), src);
293379c004Eric Schrock
294485bbbfGeorge Wilson		cap = (size == 0) ? 0 : (alloc * 100 / size);
295379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src);
296379c004Eric Schrock
297b24ab67Jeff Bonwick		spa_prop_add_list(*nvp, ZPOOL_PROP_DEDUPRATIO, NULL,
298b24ab67Jeff Bonwick		    ddt_get_pool_dedup_ratio(spa), src);
299b24ab67Jeff Bonwick
300379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
3014263d13George Wilson		    rvd->vdev_state, src);
302379c004Eric Schrock
303379c004Eric Schrock		version = spa_version(spa);
304379c004Eric Schrock		if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
305379c004Eric Schrock			src = ZPROP_SRC_DEFAULT;
306379c004Eric Schrock		else
307379c004Eric Schrock			src = ZPROP_SRC_LOCAL;
308379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
309379c004Eric Schrock	}
310990b485lling
311ad135b5Christopher Siden	if (pool != NULL) {
312ad135b5Christopher Siden		/*
313ad135b5Christopher Siden		 * The $FREE directory was introduced in SPA_VERSION_DEADLISTS,
314ad135b5Christopher Siden		 * when opening pools before this version freedir will be NULL.
315ad135b5Christopher Siden		 */
3167fd05acMatthew Ahrens		if (pool->dp_free_dir != NULL) {
317ad135b5Christopher Siden			spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, NULL,
318c137962Justin T. Gibbs			    dsl_dir_phys(pool->dp_free_dir)->dd_used_bytes,
319c137962Justin T. Gibbs			    src);
320ad135b5Christopher Siden		} else {
321ad135b5Christopher Siden			spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING,
322ad135b5Christopher Siden			    NULL, 0, src);
323ad135b5Christopher Siden		}
3247fd05acMatthew Ahrens
3257fd05acMatthew Ahrens		if (pool->dp_leak_dir != NULL) {
3267fd05acMatthew Ahrens			spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED, NULL,
327c137962Justin T. Gibbs			    dsl_dir_phys(pool->dp_leak_dir)->dd_used_bytes,
328c137962Justin T. Gibbs			    src);
3297fd05acMatthew Ahrens		} else {
3307fd05acMatthew Ahrens			spa_prop_add_list(*nvp, ZPOOL_PROP_LEAKED,
3317fd05acMatthew Ahrens			    NULL, 0, src);
3327fd05acMatthew Ahrens		}
333ad135b5Christopher Siden	}
334ad135b5Christopher Siden
3359d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
336990b485lling
3378704186Dan McDonald	if (spa->spa_comment != NULL) {
3388704186Dan McDonald		spa_prop_add_list(*nvp, ZPOOL_PROP_COMMENT, spa->spa_comment,
3398704186Dan McDonald		    0, ZPROP_SRC_LOCAL);
3408704186Dan McDonald	}
3418704186Dan McDonald
3429d82f4flling	if (spa->spa_root != NULL)
3439d82f4flling		spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
3449d82f4flling		    0, ZPROP_SRC_LOCAL);
345990b485lling
346b515258Matthew Ahrens	if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) {
347b515258Matthew Ahrens		spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL,
348b515258Matthew Ahrens		    MIN(zfs_max_recordsize, SPA_MAXBLOCKSIZE), ZPROP_SRC_NONE);
349b515258Matthew Ahrens	} else {
350b515258Matthew Ahrens		spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL,
351b515258Matthew Ahrens		    SPA_OLD_MAXBLOCKSIZE, ZPROP_SRC_NONE);
352b515258Matthew Ahrens	}
353b515258Matthew Ahrens
35454811daToomas Soome	if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_DNODE)) {
35554811daToomas Soome		spa_prop_add_list(*nvp, ZPOOL_PROP_MAXDNODESIZE, NULL,
35654811daToomas Soome		    DNODE_MAX_SIZE, ZPROP_SRC_NONE);
35754811daToomas Soome	} else {
35854811daToomas Soome		spa_prop_add_list(*nvp, ZPOOL_PROP_MAXDNODESIZE, NULL,
35954811daToomas Soome		    DNODE_MIN_SIZE, ZPROP_SRC_NONE);
36054811daToomas Soome	}
36154811daToomas Soome
362c5904d1eschrock	if ((dp = list_head(&spa->spa_config_list)) != NULL) {
363c5904d1eschrock		if (dp->scd_path == NULL) {
3649d82f4flling			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
365c5904d1eschrock			    "none", 0, ZPROP_SRC_LOCAL);
366c5904d1eschrock		} else if (strcmp(dp->scd_path, spa_config_path) != 0) {
3679d82f4flling			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
368c5904d1eschrock			    dp->scd_path, 0, ZPROP_SRC_LOCAL);
3692f8aaabeschrock		}
3702f8aaabeschrock	}
371990b485lling}
372990b485lling
373990b485lling/*
374990b485lling * Get zpool property values.
375990b485lling */
376990b485llingint
377990b485llingspa_prop_get(spa_t *spa, nvlist_t **nvp)
378990b485lling{
379b24ab67Jeff Bonwick	objset_t *mos = spa->spa_meta_objset;
380990b485lling	zap_cursor_t zc;
381990b485lling	zap_attribute_t za;
382990b485lling	int err;
383990b485lling
3849d82f4flling	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
385990b485lling
386e14bb32Jeff Bonwick	mutex_enter(&spa->spa_props_lock);
387e14bb32Jeff Bonwick
388990b485lling	/*
389990b485lling	 * Get properties from the spa config.
390990b485lling	 */
3919d82f4flling	spa_prop_get_config(spa, nvp);
392990b485lling
393990b485lling	/* If no pool property object, no more prop to get. */
394afee20eGeorge Wilson	if (mos == NULL || spa->spa_pool_props_object == 0) {
395990b485lling		mutex_exit(&spa->spa_props_lock);
396990b485lling		return (0);
397990b485lling	}
398990b485lling
399990b485lling	/*
400990b485lling	 * Get properties from the MOS pool property object.
401990b485lling	 */
402990b485lling	for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
403990b485lling	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
404990b485lling	    zap_cursor_advance(&zc)) {
405990b485lling		uint64_t intval = 0;
406990b485lling		char *strval = NULL;
407990b485lling		zprop_source_t src = ZPROP_SRC_DEFAULT;
408990b485lling		zpool_prop_t prop;
409990b485lling
4104ae5f5fAlan Somers		if ((prop = zpool_name_to_prop(za.za_name)) == ZPOOL_PROP_INVAL)
411990b485lling			continue;
412990b485lling
413990b485lling		switch (za.za_integer_length) {
414990b485lling		case 8:
415990b485lling			/* integer property */
416990b485lling			if (za.za_first_integer !=
417990b485lling			    zpool_prop_default_numeric(prop))
418990b485lling				src = ZPROP_SRC_LOCAL;
419990b485lling
420990b485lling			if (prop == ZPOOL_PROP_BOOTFS) {
421990b485lling				dsl_pool_t *dp;
422990b485lling				dsl_dataset_t *ds = NULL;
423990b485lling
424990b485lling				dp = spa_get_dsl(spa);
4253b2aab1Matthew Ahrens				dsl_pool_config_enter(dp, FTAG);
426094e47eGeorge Wilson				err = dsl_dataset_hold_obj(dp,
427094e47eGeorge Wilson				    za.za_first_integer, FTAG, &ds);
428094e47eGeorge Wilson				if (err != 0) {
4293b2aab1Matthew Ahrens					dsl_pool_config_exit(dp, FTAG);
430990b485lling					break;
431990b485lling				}
432990b485lling
4339adfa60Matthew Ahrens				strval = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN,
434990b485lling				    KM_SLEEP);
435990b485lling				dsl_dataset_name(ds, strval);
436745cd3cmaybee				dsl_dataset_rele(ds, FTAG);
4373b2aab1Matthew Ahrens				dsl_pool_config_exit(dp, FTAG);
438990b485lling			} else {
439990b485lling				strval = NULL;
440990b485lling				intval = za.za_first_integer;
441990b485lling			}
442990b485lling
4439d82f4flling			spa_prop_add_list(*nvp, prop, strval, intval, src);
444990b485lling
445990b485lling			if (strval != NULL)
4469adfa60Matthew Ahrens				kmem_free(strval, ZFS_MAX_DATASET_NAME_LEN);
447990b485lling
448990b485lling			break;
449990b485lling
450990b485lling		case 1:
451990b485lling			/* string property */
452990b485lling			strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
453990b485lling			err = zap_lookup(mos, spa->spa_pool_props_object,
454990b485lling			    za.za_name, 1, za.za_num_integers, strval);
455990b485lling			if (err) {
456990b485lling				kmem_free(strval, za.za_num_integers);
457990b485lling				break;
458990b485lling			}
4599d82f4flling			spa_prop_add_list(*nvp, prop, strval, 0, src);
460990b485lling			kmem_free(strval, za.za_num_integers);
461990b485lling			break;
462990b485lling
463990b485lling		default:
464990b485lling			break;
465990b485lling		}
466990b485lling	}
467990b485lling	zap_cursor_fini(&zc);
468990b485lling	mutex_exit(&spa->spa_props_lock);
469990b485llingout:
470990b485lling	if (err && err != ENOENT) {
471990b485lling		nvlist_free(*nvp);
4729d82f4flling		*nvp = NULL;
473990b485lling		return (err);
474990b485lling	}
475990b485lling
476990b485lling	return (0);
477990b485lling}
478990b485lling
479990b485lling/*
480990b485lling * Validate the given pool properties nvlist and modify the list
481990b485lling * for the property values to be set.
482990b485lling */
483990b485llingstatic int
484990b485llingspa_prop_validate(spa_t *spa, nvlist_t *props)
485990b485lling{
486990b485lling	nvpair_t *elem;
487990b485lling	int error = 0, reset_bootfs = 0;
488d5285caGeorge Wilson	uint64_t objnum = 0;
489ad135b5Christopher Siden	boolean_t has_feature = B_FALSE;
490990b485lling
491990b485lling	elem = NULL;
492990b485lling	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
493990b485lling		uint64_t intval;
494ad135b5Christopher Siden		char *strval, *slash, *check, *fname;
495ad135b5Christopher Siden		const char *propname = nvpair_name(elem);
496ad135b5Christopher Siden		zpool_prop_t prop = zpool_name_to_prop(propname);
497ad135b5Christopher Siden
498ad135b5Christopher Siden		switch (prop) {
4994ae5f5fAlan Somers		case ZPOOL_PROP_INVAL:
500ad135b5Christopher Siden			if (!zpool_prop_feature(propname)) {
501be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
502ad135b5Christopher Siden				break;
503ad135b5Christopher Siden			}
504990b485lling
505ad135b5Christopher Siden			/*
506ad135b5Christopher Siden			 * Sanitize the input.
507ad135b5Christopher Siden			 */
508ad135b5Christopher Siden			if (nvpair_type(elem) != DATA_TYPE_UINT64) {
509be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
510ad135b5Christopher Siden				break;
511ad135b5Christopher Siden			}
512990b485lling
513ad135b5Christopher Siden			if (nvpair_value_uint64(elem, &intval) != 0) {
514be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
515ad135b5Christopher Siden				break;
516ad135b5Christopher Siden			}
517ad135b5Christopher Siden
518ad135b5Christopher Siden			if (intval != 0) {
519be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
520ad135b5Christopher Siden				break;
521ad135b5Christopher Siden			}
522ad135b5Christopher Siden
523ad135b5Christopher Siden			fname = strchr(propname, '@') + 1;
524ad135b5Christopher Siden			if (zfeature_lookup_name(fname, NULL) != 0) {
525be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
526ad135b5Christopher Siden				break;
527ad135b5Christopher Siden			}
528ad135b5Christopher Siden
529ad135b5Christopher Siden			has_feature = B_TRUE;
530ad135b5Christopher Siden			break;
531990b485lling
532990b485lling		case ZPOOL_PROP_VERSION:
533990b485lling			error = nvpair_value_uint64(elem, &intval);
534990b485lling			if (!error &&
535ad135b5Christopher Siden			    (intval < spa_version(spa) ||
536ad135b5Christopher Siden			    intval > SPA_VERSION_BEFORE_FEATURES ||
537ad135b5Christopher Siden			    has_feature))
538be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
539990b485lling			break;
540990b485lling
541990b485lling		case ZPOOL_PROP_DELEGATION:
542990b485lling		case ZPOOL_PROP_AUTOREPLACE:
543d5b5bb2Rich Morris		case ZPOOL_PROP_LISTSNAPS:
544573ca77George Wilson		case ZPOOL_PROP_AUTOEXPAND:
545990b485lling			error = nvpair_value_uint64(elem, &intval);
546990b485lling			if (!error && intval > 1)
547be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
548990b485lling			break;
549990b485lling
550e0f1c0aOlaf Faaland		case ZPOOL_PROP_MULTIHOST:
551e0f1c0aOlaf Faaland			error = nvpair_value_uint64(elem, &intval);
552e0f1c0aOlaf Faaland			if (!error && intval > 1)
553e0f1c0aOlaf Faaland				error = SET_ERROR(EINVAL);
554e0f1c0aOlaf Faaland
555e0f1c0aOlaf Faaland			if (!error && !spa_get_hostid())
556e0f1c0aOlaf Faaland				error = SET_ERROR(ENOTSUP);
557e0f1c0aOlaf Faaland
558e0f1c0aOlaf Faaland			break;
559e0f1c0aOlaf Faaland
560990b485lling		case ZPOOL_PROP_BOOTFS:
56125f89eeJeff Bonwick			/*
56225f89eeJeff Bonwick			 * If the pool version is less than SPA_VERSION_BOOTFS,
56325f89eeJeff Bonwick			 * or the pool is still being created (version == 0),
56425f89eeJeff Bonwick			 * the bootfs property cannot be set.
56525f89eeJeff Bonwick			 */
566990b485lling			if (spa_version(spa) < SPA_VERSION_BOOTFS) {
567be6fd75Matthew Ahrens				error = SET_ERROR(ENOTSUP);
568990b485lling				break;
569990b485lling			}
570990b485lling
571990b485lling			/*
57215e6edfgw			 * Make sure the vdev config is bootable
573990b485lling			 */
57415e6edfgw			if (!vdev_is_bootable(spa->spa_root_vdev)) {
575be6fd75Matthew Ahrens				error = SET_ERROR(ENOTSUP);
576990b485lling				break;
577990b485lling			}
578990b485lling
579990b485lling			reset_bootfs = 1;
580990b485lling
581990b485lling			error = nvpair_value_string(elem, &strval);
582990b485lling
583990b485lling			if (!error) {
584ad135b5Christopher Siden				objset_t *os;
585b515258Matthew Ahrens				uint64_t propval;
58615e6edfgw
587990b485lling				if (strval == NULL || strval[0] == '\0') {
588990b485lling					objnum = zpool_prop_default_numeric(
589990b485lling					    ZPOOL_PROP_BOOTFS);
590990b485lling					break;
591990b485lling				}
592990b485lling
593094e47eGeorge Wilson				error = dmu_objset_hold(strval, FTAG, &os);
594094e47eGeorge Wilson				if (error != 0)
595990b485lling					break;
59615e6edfgw
597b515258Matthew Ahrens				/*
598b515258Matthew Ahrens				 * Must be ZPL, and its property settings
59954811daToomas Soome				 * must be supported.
600b515258Matthew Ahrens				 */
601503ad85Matthew Ahrens
602503ad85Matthew Ahrens				if (dmu_objset_type(os) != DMU_OST_ZFS) {
603be6fd75Matthew Ahrens					error = SET_ERROR(ENOTSUP);
6043b2aab1Matthew Ahrens				} else if ((error =
6053b2aab1Matthew Ahrens				    dsl_prop_get_int_ds(dmu_objset_ds(os),
60615e6edfgw				    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
607b515258Matthew Ahrens				    &propval)) == 0 &&
608b515258Matthew Ahrens				    !BOOTFS_COMPRESS_VALID(propval)) {
609b515258Matthew Ahrens					error = SET_ERROR(ENOTSUP);
61015e6edfgw				} else {
61115e6edfgw					objnum = dmu_objset_id(os);
61215e6edfgw				}
613503ad85Matthew Ahrens				dmu_objset_rele(os, FTAG);
614990b485lling			}
615990b485lling			break;
616e14bb32Jeff Bonwick
6170a4e951gw		case ZPOOL_PROP_FAILUREMODE:
6180a4e951gw			error = nvpair_value_uint64(elem, &intval);
6190a4e951gw			if (!error && (intval < ZIO_FAILURE_MODE_WAIT ||
6200a4e951gw			    intval > ZIO_FAILURE_MODE_PANIC))
621be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
6220a4e951gw
6230a4e951gw			/*
6240a4e951gw			 * This is a special case which only occurs when
6250a4e951gw			 * the pool has completely failed. This allows
6260a4e951gw			 * the user to change the in-core failmode property
6270a4e951gw			 * without syncing it out to disk (I/Os might
6280a4e951gw			 * currently be blocked). We do this by returning
6290a4e951gw			 * EIO to the caller (spa_prop_set) to trick it
6300a4e951gw			 * into thinking we encountered a property validation
6310a4e951gw			 * error.
6320a4e951gw			 */
633e14bb32Jeff Bonwick			if (!error && spa_suspended(spa)) {
6340a4e951gw				spa->spa_failmode = intval;
635be6fd75Matthew Ahrens				error = SET_ERROR(EIO);
6360a4e951gw			}
6370a4e951gw			break;
6382f8aaabeschrock
6392f8aaabeschrock		case ZPOOL_PROP_CACHEFILE:
6402f8aaabeschrock			if ((error = nvpair_value_string(elem, &strval)) != 0)
6412f8aaabeschrock				break;
6422f8aaabeschrock
6432f8aaabeschrock			if (strval[0] == '\0')
6442f8aaabeschrock				break;
6452f8aaabeschrock
6462f8aaabeschrock			if (strcmp(strval, "none") == 0)
6472f8aaabeschrock				break;
6482f8aaabeschrock
6492f8aaabeschrock			if (strval[0] != '/') {
650be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
6512f8aaabeschrock				break;
6522f8aaabeschrock			}
6532f8aaabeschrock
6542f8aaabeschrock			slash = strrchr(strval, '/');
6552f8aaabeschrock			ASSERT(slash != NULL);
6562f8aaabeschrock
6572f8aaabeschrock			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
6582f8aaabeschrock			    strcmp(slash, "/..") == 0)
659be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
6602f8aaabeschrock			break;
661b24ab67Jeff Bonwick
6628704186Dan McDonald		case ZPOOL_PROP_COMMENT:
6638704186Dan McDonald			if ((error = nvpair_value_string(elem, &strval)) != 0)
6648704186Dan McDonald				break;
6658704186Dan McDonald			for (check = strval; *check != '\0'; check++) {
6668704186Dan McDonald				/*
6678704186Dan McDonald				 * The kernel doesn't have an easy isprint()
6688704186Dan McDonald				 * check.  For this kernel check, we merely
6698704186Dan McDonald				 * check ASCII apart from DEL.  Fix this if
6708704186Dan McDonald				 * there is an easy-to-use kernel isprint().
6718704186Dan McDonald				 */
6728704186Dan McDonald				if (*check >= 0x7f) {
673be6fd75Matthew Ahrens					error = SET_ERROR(EINVAL);
6748704186Dan McDonald					break;
6758704186Dan McDonald				}
6768704186Dan McDonald			}
6778704186Dan McDonald			if (strlen(strval) > ZPROP_MAX_COMMENT)
6788704186Dan McDonald				error = E2BIG;
6798704186Dan McDonald			break;
6808704186Dan McDonald
681b24ab67Jeff Bonwick		case ZPOOL_PROP_DEDUPDITTO:
682b24ab67Jeff Bonwick			if (spa_version(spa) < SPA_VERSION_DEDUP)
683be6fd75Matthew Ahrens				error = SET_ERROR(ENOTSUP);
684b24ab67Jeff Bonwick			else
685b24ab67Jeff Bonwick				error = nvpair_value_uint64(elem, &intval);
686b24ab67Jeff Bonwick			if (error == 0 &&
687b24ab67Jeff Bonwick			    intval != 0 && intval < ZIO_DEDUPDITTO_MIN)
688be6fd75Matthew Ahrens				error = SET_ERROR(EINVAL);
689b24ab67Jeff Bonwick			break;
690990b485lling		}
691990b485lling
692990b485lling		if (error)
693990b485lling			break;
694990b485lling	}
695990b485lling
696990b485lling	if (!error && reset_bootfs) {
697990b485lling		error = nvlist_remove(props,
698990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING);
699990b485lling
700990b485lling		if (!error) {
701990b485lling			error = nvlist_add_uint64(props,
702990b485lling			    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum);
703990b485lling		}
704990b485lling	}
705990b485lling
706990b485lling	return (error);
707990b485lling}
708990b485lling
709379c004Eric Schrockvoid
710379c004Eric Schrockspa_configfile_set(spa_t *spa, nvlist_t *nvp, boolean_t need_sync)
711379c004Eric Schrock{
712379c004Eric Schrock	char *cachefile;
713379c004Eric Schrock	spa_config_dirent_t *dp;
714379c004Eric Schrock
715379c004Eric Schrock	if (nvlist_lookup_string(nvp, zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
716379c004Eric Schrock	    &cachefile) != 0)
717379c004Eric Schrock		return;
718379c004Eric Schrock
719379c004Eric Schrock	dp = kmem_alloc(sizeof (spa_config_dirent_t),
720379c004Eric Schrock	    KM_SLEEP);
721379c004Eric Schrock
722379c004Eric Schrock	if (cachefile[0] == '\0')
723379c004Eric Schrock		dp->scd_path = spa_strdup(spa_config_path);
724379c004Eric Schrock	else if (strcmp(cachefile, "none") == 0)
725379c004Eric Schrock		dp->scd_path = NULL;
726379c004Eric Schrock	else
727379c004Eric Schrock		dp->scd_path = spa_strdup(cachefile);
728379c004Eric Schrock
729379c004Eric Schrock	list_insert_head(&spa->spa_config_list, dp);
730379c004Eric Schrock	if (need_sync)
731379c004Eric Schrock		spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
732379c004Eric Schrock}
733379c004Eric Schrock
734990b485llingint
735990b485llingspa_prop_set(spa_t *spa, nvlist_t *nvp)
736990b485lling{
737990b485lling	int error;
738ad135b5Christopher Siden	nvpair_t *elem = NULL;
739379c004Eric Schrock	boolean_t need_sync = B_FALSE;
740990b485lling
741990b485lling	if ((error = spa_prop_validate(spa, nvp)) != 0)
742990b485lling		return (error);
743990b485lling
744379c004Eric Schrock	while ((elem = nvlist_next_nvpair(nvp, elem)) != NULL) {
745ad135b5Christopher Siden		zpool_prop_t prop = zpool_name_to_prop(nvpair_name(elem));
746379c004Eric Schrock
747f9af39bGeorge Wilson		if (prop == ZPOOL_PROP_CACHEFILE ||
748f9af39bGeorge Wilson		    prop == ZPOOL_PROP_ALTROOT ||
749f9af39bGeorge Wilson		    prop == ZPOOL_PROP_READONLY)
750379c004Eric Schrock			continue;
751379c004Eric Schrock
7524ae5f5fAlan Somers		if (prop == ZPOOL_PROP_VERSION || prop == ZPOOL_PROP_INVAL) {
753ad135b5Christopher Siden			uint64_t ver;
754ad135b5Christopher Siden
755ad135b5Christopher Siden			if (prop == ZPOOL_PROP_VERSION) {
756ad135b5Christopher Siden				VERIFY(nvpair_value_uint64(elem, &ver) == 0);
757ad135b5Christopher Siden			} else {
758ad135b5Christopher Siden				ASSERT(zpool_prop_feature(nvpair_name(elem)));
759ad135b5Christopher Siden				ver = SPA_VERSION_FEATURES;
760ad135b5Christopher Siden				need_sync = B_TRUE;
761ad135b5Christopher Siden			}
762ad135b5Christopher Siden
763ad135b5Christopher Siden			/* Save time if the version is already set. */
764ad135b5Christopher Siden			if (ver == spa_version(spa))
765ad135b5Christopher Siden				continue;
766ad135b5Christopher Siden
767ad135b5Christopher Siden			/*
768ad135b5Christopher Siden			 * In addition to the pool directory object, we might
769ad135b5Christopher Siden			 * create the pool properties object, the features for
770ad135b5Christopher Siden			 * read object, the features for write object, or the
771ad135b5Christopher Siden			 * feature descriptions object.
772ad135b5Christopher Siden			 */
7733b2aab1Matthew Ahrens			error = dsl_sync_task(spa->spa_name, NULL,
7747d46dc6Matthew Ahrens			    spa_sync_version, &ver,
7757d46dc6Matthew Ahrens			    6, ZFS_SPACE_CHECK_RESERVED);
776ad135b5Christopher Siden			if (error)
777ad135b5Christopher Siden				return (error);
778ad135b5Christopher Siden			continue;
779ad135b5Christopher Siden		}
780ad135b5Christopher Siden
781379c004Eric Schrock		need_sync = B_TRUE;
782379c004Eric Schrock		break;
783379c004Eric Schrock	}
784379c004Eric Schrock
785ad135b5Christopher Siden	if (need_sync) {
7863b2aab1Matthew Ahrens		return (dsl_sync_task(spa->spa_name, NULL, spa_sync_props,
7877d46dc6Matthew Ahrens		    nvp, 6, ZFS_SPACE_CHECK_RESERVED));
788ad135b5Christopher Siden	}
789ad135b5Christopher Siden
790ad135b5Christopher Siden	return (0);
791990b485lling}
792990b485lling
793990b485lling/*
794990b485lling * If the bootfs property value is dsobj, clear it.
795990b485lling */
796990b485llingvoid
797990b485llingspa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
798990b485