fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
013023d4ed2f6d0cf75380ec686a4aac392b4e43Martin Matuska * Copyright (c) 2013 Martin Matuska. All rights reserved.
d09e4475f635b6f66ee68d8c17a32bba7be17c96Alex Wilson * Copyright 2015, Joyent, Inc.
d09e4475f635b6f66ee68d8c17a32bba7be17c96Alex Wilsondodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The setonce properties are read-only, BUT they still
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * have a default value that can be used as the initial
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson int intsz, int numints, void *buf, char *setpoint, boolean_t snapshot)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Note: dd may become NULL, therefore we shouldn't dereference it
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * after this loop.
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Check for a local value. */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Skip the check for a received value if there is an explicit
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * inheritance entry.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs err = zap_contains(mos, dsl_dir_phys(dd)->dd_props_zapobj,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Check for a received value. */
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs err = zap_lookup(mos, dsl_dir_phys(dd)->dd_props_zapobj,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * If we found an explicit inheritance entry, err is zero even
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * though we haven't yet found the value, so reinitializing err
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * at the end of the loop (instead of at the beginning) ensures
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * that err has a valid post-loop value.
bb0ade0978a02d3fe0b0165cd4725fdcb593fbfbahrensdsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson int intsz, int numints, void *buf, char *setpoint)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs zapobj = dsl_dataset_phys(ds)->ds_props_obj;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Check for a local value. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson err = zap_lookup(mos, zapobj, propname, intsz, numints, buf);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Skip the check for a received value if there is an explicit
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * inheritance entry.
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson char *inheritstr = kmem_asprintf("%s%s", propname,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Check for a received value. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson char *recvdstr = kmem_asprintf("%s%s", propname,
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs intsz, numints, buf, setpoint, ds->ds_is_snapshot));
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbsdsl_prop_record_find(dsl_dir_t *dd, const char *propname)
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs pr != NULL; pr = list_next(&dd->dd_props, pr)) {
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbsdsl_prop_record_create(dsl_dir_t *dd, const char *propname)
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs pr = kmem_alloc(sizeof (dsl_prop_record_t), KM_SLEEP);
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs list_create(&pr->pr_cbs, sizeof (dsl_prop_cb_record_t),
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs list_create(&dd->dd_props, sizeof (dsl_prop_record_t),
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs while ((pr = list_remove_head(&dd->dd_props)) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Register interest in the named property. We'll call the callback
fa9e4066f08beec538e775443c5be79dd423fcabahrens * once to notify it of the current property value, and again each time
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the property changes, until this callback is unregistered.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return 0 on success, errno if the prop is not an integer value.
fa9e4066f08beec538e775443c5be79dd423fcabahrensdsl_prop_register(dsl_dataset_t *ds, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = dsl_prop_get_int_ds(ds, propname, &value);
fa9e4066f08beec538e775443c5be79dd423fcabahrens cbr = kmem_alloc(sizeof (dsl_prop_cb_record_t), KM_SLEEP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
bb0ade0978a02d3fe0b0165cd4725fdcb593fbfbahrensdsl_prop_get(const char *dsname, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_prop_get_ds(dmu_objset_ds(os), propname,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Get the current property value. It may have changed by the time this
fa9e4066f08beec538e775443c5be79dd423fcabahrens * function returns, so it is NOT safe to follow up with
fa9e4066f08beec538e775443c5be79dd423fcabahrens * dsl_prop_register() and assume that the value has not changed in
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return 0 on success, ENOENT if ddname is invalid.
fa9e4066f08beec538e775443c5be79dd423fcabahrensdsl_prop_get_integer(const char *ddname, const char *propname,
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (dsl_prop_get(ddname, propname, 8, 1, valuep, setpoint));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_get_int_ds(dsl_dataset_t *ds, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_prop_get_ds(ds, propname, 8, 1, valuep, NULL));
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Predict the effective value of the given special property if it were set with
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * the given value and source. This is not a general purpose function. It exists
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * only to handle the special requirements of the quota and reservation
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * properties. The fact that these properties are non-inheritable greatly
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * simplifies the prediction logic.
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Returns 0 on success, a positive error code on failure, or -1 if called with
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * a property not handled by this function.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_predict(dsl_dir_t *dd, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zprop_source_t source, uint64_t value, uint64_t *newvalp)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson return (-1);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Revert to the received value, if any. */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = zap_lookup(mos, zapobj, recvdstr, 8, 1, newvalp);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * If there's no local setting, then the new received value will
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * be the effective value.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = zap_lookup(mos, zapobj, propname, 8, 1, newvalp);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * We're clearing the received value, so the local setting (if
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * it exists) remains the effective value.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = zap_lookup(mos, zapobj, propname, 8, 1, newvalp);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens panic("unexpected property source: %d", source);
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * Unregister all callbacks that are registered with the
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * given callback argument.
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbsdsl_prop_unregister_all(dsl_dataset_t *ds, void *cbarg)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens/* ARGSUSED */
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_notify_all_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * Callback entries do not have holds on their
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * datasets so that datasets with registered
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * callbacks are still eligible for eviction.
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * Unlike operations to update properties on a
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * single dataset, we are performing a recursive
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * descent of related head datasets. The caller
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * of this function only has a dataset hold on
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * the passed in head dataset, not the snapshots
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * associated with this dataset. Without a hold,
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * the dataset pointer within callback records
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * for snapshots can be invalidated by eviction
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * at any time.
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * Use dsl_dataset_try_add_ref() to verify
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * that the dataset for a snapshot has not
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * begun eviction processing and to prevent
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * eviction from occurring for the duration of
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * the callback. If the hold attempt fails,
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * this object is already being evicted and the
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * callback can be safely ignored.
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs !dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * Update all property values for ddobj & its descendants. This is used
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * when renaming the dir.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) dmu_objset_find_dp(dp, dd->dd_object, dsl_prop_notify_all_cb,
fa9e4066f08beec538e775443c5be79dd423fcabahrensdsl_prop_changed_notify(dsl_pool_t *dp, uint64_t ddobj,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens ASSERT(RRW_WRITE_HELD(&dp->dp_config_rwlock));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = dsl_dir_hold_obj(dp, ddobj, NULL, FTAG, &dd);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the prop is set here, then this change is not
fa9e4066f08beec538e775443c5be79dd423fcabahrens * being inherited here or below; stop the recursion.
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs err = zap_contains(mos, dsl_dir_phys(dd)->dd_props_zapobj,
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (err == 0) {
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * cbr->cbr_ds may be invalidated due to eviction,
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * requiring the use of dsl_dataset_try_add_ref().
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * See comment block in dsl_prop_notify_all_cb()
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * for details.
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs if (!dsl_dataset_try_add_ref(dp, cbr->cbr_ds, FTAG))
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs propobj = dsl_dataset_phys(cbr->cbr_ds)->ds_props_obj;
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * If the property is not set on this ds, then it is
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs * inherited here; call the callback.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zprop_source_t source, int intsz, int numints, const void *value,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
d09e4475f635b6f66ee68d8c17a32bba7be17c96Alex Wilson isint = (dodefault(zfs_name_to_prop(propname), 8, 1, &intval) == 0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_props_obj == 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs zapobj = dsl_dataset_phys(ds)->ds_props_obj;
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs zapobj = dsl_dir_phys(ds->ds_dir)->dd_props_zapobj;
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson inheritstr = kmem_asprintf("%s%s", propname, ZPROP_INHERIT_SUFFIX);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson recvdstr = kmem_asprintf("%s%s", propname, ZPROP_RECVD_SUFFIX);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * revert to received value, if any (inherit -S)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - remove propname
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - remove propname$inherit
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * remove propname$inherit
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * set propname -> value
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * explicitly inherit
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - remove propname
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - set propname$inherit
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_get_int_ds(ds, ZPROP_HAS_RECVD, &dummy) == 0) {
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * set propname$recvd -> value
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson case (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED):
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * clear local and received settings
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - remove propname
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - remove propname$inherit
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * - remove propname$recvd
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* FALLTHRU */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * remove propname$recvd
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson cmn_err(CE_PANIC, "unexpected property source: %d", source);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_prop_get_int_ds(ds, propname, &intval));
bb0ade0978a02d3fe0b0165cd4725fdcb593fbfbahrens * It's a snapshot; nothing can inherit this
bb0ade0978a02d3fe0b0165cd4725fdcb593fbfbahrens * property, so just look for callbacks on this
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson ds->ds_dir->dd_object, propname, intval, TRUE);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens spa_history_log_internal_ds(ds, (source == ZPROP_SRC_NONE ||
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens source == ZPROP_SRC_INHERITED) ? "inherit" : "set", tx,
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens "%s=%s", propname, (valstr == NULL ? "" : valstr));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_set_int(const char *dsname, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_set_string(const char *dsname, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_inherit(const char *dsname, const char *propname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens err = dsl_dataset_hold(dp, dpsa->dpsa_dsname, FTAG, &ds);
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor version = spa_version(ds->ds_dir->dd_pool->dp_spa);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens while ((elem = nvlist_next_nvpair(dpsa->dpsa_props, elem)) != NULL) {
478ed9ada0b6efe1318150a700986aa47e6a926dEric Taylor if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
bc9014e6a81272073b9854d9f65dd59e18d18c35Justin Gibbs if (ds->ds_is_snapshot && version < SPA_VERSION_SNAP_PROPS) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * dsl_prop_get_all_impl() returns properties in this
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens nvlist_t *attrs = fnvpair_value_nvlist(pair);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens pair = fnvlist_lookup_nvpair(attrs, ZPROP_VALUE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens const char *value = fnvpair_value_string(pair);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_set_sync_impl(ds, nvpair_name(pair),
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens } else if (nvpair_type(pair) == DATA_TYPE_UINT64) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens uint64_t intval = fnvpair_value_uint64(pair);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_set_sync_impl(ds, nvpair_name(pair),
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens } else if (nvpair_type(pair) == DATA_TYPE_BOOLEAN) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_set_sync_impl(ds, nvpair_name(pair),
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_dataset_hold(dp, dpsa->dpsa_dsname, FTAG, &ds));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_props_set_sync_impl(ds, dpsa->dpsa_source, dpsa->dpsa_props, tx);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * All-or-nothing; if any prop can't be set, nothing will be modified.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_props_set(const char *dsname, zprop_source_t source, nvlist_t *props)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * If the source includes NONE, then we will only be removing entries
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens * from the ZAP object. In that case don't check for ENOSPC.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens return (dsl_sync_task(dsname, dsl_props_set_check, dsl_props_set_sync,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson DSL_PROP_GET_INHERITING = 0x1, /* searching parent of target ds */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson DSL_PROP_GET_SNAPSHOT = 0x2, /* snapshot dataset */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson DSL_PROP_GET_LOCAL = 0x4, /* local properties */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson DSL_PROP_GET_RECEIVED = 0x8 /* received properties */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Ericksondsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson const char *setpoint, dsl_prop_getflags_t flags, nvlist_t *nv)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Skip local properties if we only want received
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * properties.
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson } else if (strcmp(suffix, ZPROP_INHERIT_SUFFIX) == 0) {
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Skip explicitly inherited entries. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson } else if (strcmp(suffix, ZPROP_RECVD_SUFFIX) == 0) {
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson (void) strncpy(buf, za.za_name, (suffix - za.za_name));
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Skip if locally overridden. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Skip if explicitly inherited. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * For backward compatibility, skip suffixes we don't
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * recognize.
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Skip non-inheritable properties. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson if ((flags & DSL_PROP_GET_INHERITING) && prop != ZPROP_INVAL &&
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Skip properties not valid for this type. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson if ((flags & DSL_PROP_GET_SNAPSHOT) && prop != ZPROP_INVAL &&
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson !zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT))
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Skip properties already defined. */
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * String property
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Integer property
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, source) == 0);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
7f7322febbcfe774b7270abc3b191c094bfcc517eschrock * Iterate over all properties for this dataset and return them in an nvlist.
92241e0b80813d0b83c08e730a29b9d1831794fcTom Ericksondsl_prop_get_all_ds(dsl_dataset_t *ds, nvlist_t **nvp,
7f7322febbcfe774b7270abc3b191c094bfcc517eschrock VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs if (dsl_dataset_phys(ds)->ds_props_obj != 0) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dataset_phys(ds)->ds_props_obj, setpoint, flags, *nvp);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson if (dd != ds->ds_dir || (flags & DSL_PROP_GET_SNAPSHOT)) {
c1379625401dfbe1c39b79136dd384a571d47fdeJustin T. Gibbs dsl_dir_phys(dd)->dd_props_zapobj, setpoint, flags, *nvp);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_get_integer(dsname, ZPROP_HAS_RECVD, &dummy, NULL));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_set_hasrecvd_impl(const char *dsname, zprop_source_t source)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_prop_set_int(dsname, ZPROP_HAS_RECVD, source, 0);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Call after successfully receiving properties to ensure that only the first
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * receive on or after SPA_VERSION_RECVD_PROPS blows away local properties.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_prop_set_hasrecvd_impl(dsname, ZPROP_SRC_LOCAL);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_prop_set_hasrecvd_impl(dsname, ZPROP_SRC_NONE));
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson return (dsl_prop_get_all_ds(os->os_dsl_dataset, nvp, 0));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensdsl_prop_get_received(const char *dsname, nvlist_t **nvp)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * Received properties are not distinguishable from local properties
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * until the dataset has received properties on or after
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson * SPA_VERSION_RECVD_PROPS.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_prop_getflags_t flags = (dsl_prop_get_hasrecvd(dsname) ?
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_prop_get_all_ds(os->os_dsl_dataset, nvp, flags);
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrensdsl_prop_nvlist_add_uint64(nvlist_t *nv, zfs_prop_t prop, uint64_t value)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson if (nvlist_lookup_nvlist(nv, propname, &propval) == 0) {
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrens VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson /* Indicate the default source if we can. */
d09e4475f635b6f66ee68d8c17a32bba7be17c96Alex Wilson if (dodefault(prop, 8, 1, &default_value) == 0 &&
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, "") == 0);
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_add_nvlist(nv, propname, propval) == 0);
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrensdsl_prop_nvlist_add_string(nvlist_t *nv, zfs_prop_t prop, const char *value)
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson if (nvlist_lookup_nvlist(nv, propname, &propval) == 0) {
92241e0b80813d0b83c08e730a29b9d1831794fcTom Erickson VERIFY(nvlist_add_string(propval, ZPROP_VALUE, value) == 0);
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrens VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling VERIFY(nvlist_add_string(propval, ZPROP_VALUE, value) == 0);