150 if (err == ENOENT)
151 err = dodefault(propname, intsz, numints, buf);
152
153 strfree(inheritstr);
154 strfree(recvdstr);
155
156 return (err);
157 }
158
159 int
160 dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
161 int intsz, int numints, void *buf, char *setpoint)
162 {
163 zfs_prop_t prop = zfs_name_to_prop(propname);
164 boolean_t inheritable;
165 boolean_t snapshot;
166 uint64_t zapobj;
167
168 ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
169 inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
170 snapshot = (ds->ds_phys != NULL && dsl_dataset_is_snapshot(ds));
171 zapobj = (ds->ds_phys == NULL ? 0 : ds->ds_phys->ds_props_obj);
172
173 if (zapobj != 0) {
174 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
175 int err;
176
177 ASSERT(snapshot);
178
179 /* Check for a local value. */
180 err = zap_lookup(mos, zapobj, propname, intsz, numints, buf);
181 if (err != ENOENT) {
182 if (setpoint != NULL && err == 0)
183 dsl_dataset_name(ds, setpoint);
184 return (err);
185 }
186
187 /*
188 * Skip the check for a received value if there is an explicit
189 * inheritance entry.
190 */
191 if (inheritable) {
526 }
527
528 void
529 dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
530 zprop_source_t source, int intsz, int numints, const void *value,
531 dmu_tx_t *tx)
532 {
533 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
534 uint64_t zapobj, intval, dummy;
535 int isint;
536 char valbuf[32];
537 const char *valstr = NULL;
538 char *inheritstr;
539 char *recvdstr;
540 char *tbuf = NULL;
541 int err;
542 uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
543
544 isint = (dodefault(propname, 8, 1, &intval) == 0);
545
546 if (ds->ds_phys != NULL && dsl_dataset_is_snapshot(ds)) {
547 ASSERT(version >= SPA_VERSION_SNAP_PROPS);
548 if (ds->ds_phys->ds_props_obj == 0) {
549 dmu_buf_will_dirty(ds->ds_dbuf, tx);
550 ds->ds_phys->ds_props_obj =
551 zap_create(mos,
552 DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
553 }
554 zapobj = ds->ds_phys->ds_props_obj;
555 } else {
556 zapobj = ds->ds_dir->dd_phys->dd_props_zapobj;
557 }
558
559 if (version < SPA_VERSION_RECVD_PROPS) {
560 zfs_prop_t prop = zfs_name_to_prop(propname);
561 if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION)
562 return;
563
564 if (source & ZPROP_SRC_NONE)
565 source = ZPROP_SRC_NONE;
566 else if (source & ZPROP_SRC_RECEIVED)
627 err = zap_remove(mos, zapobj, inheritstr, tx);
628 ASSERT(err == 0 || err == ENOENT);
629 /* FALLTHRU */
630 case (ZPROP_SRC_NONE | ZPROP_SRC_RECEIVED):
631 /*
632 * remove propname$recvd
633 */
634 err = zap_remove(mos, zapobj, recvdstr, tx);
635 ASSERT(err == 0 || err == ENOENT);
636 break;
637 default:
638 cmn_err(CE_PANIC, "unexpected property source: %d", source);
639 }
640
641 strfree(inheritstr);
642 strfree(recvdstr);
643
644 if (isint) {
645 VERIFY0(dsl_prop_get_int_ds(ds, propname, &intval));
646
647 if (ds->ds_phys != NULL && dsl_dataset_is_snapshot(ds)) {
648 dsl_prop_cb_record_t *cbr;
649 /*
650 * It's a snapshot; nothing can inherit this
651 * property, so just look for callbacks on this
652 * ds here.
653 */
654 mutex_enter(&ds->ds_dir->dd_lock);
655 for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr;
656 cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) {
657 if (cbr->cbr_ds == ds &&
658 strcmp(cbr->cbr_propname, propname) == 0)
659 cbr->cbr_func(cbr->cbr_arg, intval);
660 }
661 mutex_exit(&ds->ds_dir->dd_lock);
662 } else {
663 dsl_prop_changed_notify(ds->ds_dir->dd_pool,
664 ds->ds_dir->dd_object, propname, intval, TRUE);
665 }
666
667 (void) snprintf(valbuf, sizeof (valbuf),
|
150 if (err == ENOENT)
151 err = dodefault(propname, intsz, numints, buf);
152
153 strfree(inheritstr);
154 strfree(recvdstr);
155
156 return (err);
157 }
158
159 int
160 dsl_prop_get_ds(dsl_dataset_t *ds, const char *propname,
161 int intsz, int numints, void *buf, char *setpoint)
162 {
163 zfs_prop_t prop = zfs_name_to_prop(propname);
164 boolean_t inheritable;
165 boolean_t snapshot;
166 uint64_t zapobj;
167
168 ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool));
169 inheritable = (prop == ZPROP_INVAL || zfs_prop_inheritable(prop));
170 snapshot = (DS_HAS_PHYS(ds) && dsl_dataset_is_snapshot(ds));
171 zapobj = (DS_HAS_PHYS(ds) ? ds->ds_phys->ds_props_obj : 0);
172
173 if (zapobj != 0) {
174 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
175 int err;
176
177 ASSERT(snapshot);
178
179 /* Check for a local value. */
180 err = zap_lookup(mos, zapobj, propname, intsz, numints, buf);
181 if (err != ENOENT) {
182 if (setpoint != NULL && err == 0)
183 dsl_dataset_name(ds, setpoint);
184 return (err);
185 }
186
187 /*
188 * Skip the check for a received value if there is an explicit
189 * inheritance entry.
190 */
191 if (inheritable) {
526 }
527
528 void
529 dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
530 zprop_source_t source, int intsz, int numints, const void *value,
531 dmu_tx_t *tx)
532 {
533 objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset;
534 uint64_t zapobj, intval, dummy;
535 int isint;
536 char valbuf[32];
537 const char *valstr = NULL;
538 char *inheritstr;
539 char *recvdstr;
540 char *tbuf = NULL;
541 int err;
542 uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
543
544 isint = (dodefault(propname, 8, 1, &intval) == 0);
545
546 if (DS_HAS_PHYS(ds) && dsl_dataset_is_snapshot(ds)) {
547 ASSERT(version >= SPA_VERSION_SNAP_PROPS);
548 if (ds->ds_phys->ds_props_obj == 0) {
549 dmu_buf_will_dirty(ds->ds_dbuf, tx);
550 ds->ds_phys->ds_props_obj =
551 zap_create(mos,
552 DMU_OT_DSL_PROPS, DMU_OT_NONE, 0, tx);
553 }
554 zapobj = ds->ds_phys->ds_props_obj;
555 } else {
556 zapobj = ds->ds_dir->dd_phys->dd_props_zapobj;
557 }
558
559 if (version < SPA_VERSION_RECVD_PROPS) {
560 zfs_prop_t prop = zfs_name_to_prop(propname);
561 if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION)
562 return;
563
564 if (source & ZPROP_SRC_NONE)
565 source = ZPROP_SRC_NONE;
566 else if (source & ZPROP_SRC_RECEIVED)
627 err = zap_remove(mos, zapobj, inheritstr, tx);
628 ASSERT(err == 0 || err == ENOENT);
629 /* FALLTHRU */
630 case (ZPROP_SRC_NONE | ZPROP_SRC_RECEIVED):
631 /*
632 * remove propname$recvd
633 */
634 err = zap_remove(mos, zapobj, recvdstr, tx);
635 ASSERT(err == 0 || err == ENOENT);
636 break;
637 default:
638 cmn_err(CE_PANIC, "unexpected property source: %d", source);
639 }
640
641 strfree(inheritstr);
642 strfree(recvdstr);
643
644 if (isint) {
645 VERIFY0(dsl_prop_get_int_ds(ds, propname, &intval));
646
647 if (DS_HAS_PHYS(ds) && dsl_dataset_is_snapshot(ds)) {
648 dsl_prop_cb_record_t *cbr;
649 /*
650 * It's a snapshot; nothing can inherit this
651 * property, so just look for callbacks on this
652 * ds here.
653 */
654 mutex_enter(&ds->ds_dir->dd_lock);
655 for (cbr = list_head(&ds->ds_dir->dd_prop_cbs); cbr;
656 cbr = list_next(&ds->ds_dir->dd_prop_cbs, cbr)) {
657 if (cbr->cbr_ds == ds &&
658 strcmp(cbr->cbr_propname, propname) == 0)
659 cbr->cbr_func(cbr->cbr_arg, intval);
660 }
661 mutex_exit(&ds->ds_dir->dd_lock);
662 } else {
663 dsl_prop_changed_notify(ds->ds_dir->dd_pool,
664 ds->ds_dir->dd_object, propname, intval, TRUE);
665 }
666
667 (void) snprintf(valbuf, sizeof (valbuf),
|