Print this page
cstyle fixes
dsl_dataset_set_fsid_guid should use ZFS_SPACE_CHECK_RESERVED
dsl_dataset_set_fsid_guid _check and _sync func declared static,
removed from dsl_dataset.h
rewrite unique_valid
6333 ZFS should let the user specify or modify the fsid_guid of a dataset

*** 1796,1805 **** --- 1796,1807 ---- ds->ds_quota); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRESERVATION, ds->ds_reserved); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_GUID, dsl_dataset_phys(ds)->ds_guid); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_FSID_GUID, + dsl_dataset_phys(ds)->ds_fsid_guid); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_UNIQUE, dsl_dataset_phys(ds)->ds_unique_bytes); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_OBJSETID, ds->ds_object); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USERREFS,
*** 3503,3507 **** --- 3505,3577 ---- { return (dsl_dataset_is_zapified(ds) && zap_contains(ds->ds_dir->dd_pool->dp_meta_objset, ds->ds_object, DS_FIELD_RESUME_TOGUID) == 0); } + + typedef struct dsl_dataset_set_fsid_guid_arg { + const char *ddsfg_name; + uint64_t ddsfg_value; + } dsl_dataset_set_fsid_guid_arg_t; + + static int + dsl_dataset_set_fsid_guid_check(void *arg, dmu_tx_t *tx) + { + int err = 0; + dsl_dataset_set_fsid_guid_arg_t *ddsfg = arg; + dsl_pool_t *dp = dmu_tx_pool(tx); + dsl_dataset_t *ds; + uint64_t newval; + + newval = ddsfg->ddsfg_value; + + err = dsl_dataset_hold(dp, ddsfg->ddsfg_name, FTAG, &ds); + if (err != 0) + return (err); + + /* Check if the FS is mounted */ + if (ds->ds_owner != NULL) { + dsl_dataset_rele(ds, FTAG); + return (SET_ERROR(EBUSY)); + } + dsl_dataset_rele(ds, FTAG); + + if (!unique_valid(newval)) + return (SET_ERROR(EEXIST)); + + return (err); + } + + static void + dsl_dataset_set_fsid_guid_sync(void *arg, dmu_tx_t *tx) + { + dsl_dataset_set_fsid_guid_arg_t *ddsfg = arg; + dsl_pool_t *dp = dmu_tx_pool(tx); + dsl_dataset_t *ds; + uint64_t newval; + + VERIFY0(dsl_dataset_hold(dp, ddsfg->ddsfg_name, FTAG, &ds)); + + newval = ddsfg->ddsfg_value; + + dmu_buf_will_dirty(ds->ds_dbuf, tx); + mutex_enter(&ds->ds_lock); + ds->ds_fsid_guid = newval; + dsl_dataset_phys(ds)->ds_fsid_guid = newval; + mutex_exit(&ds->ds_lock); + + dsl_dataset_rele(ds, FTAG); + } + + int + dsl_dataset_set_fsid_guid(const char *ddname, zprop_source_t source, + uint64_t fsid_guid) + { + dsl_dataset_set_fsid_guid_arg_t ddsfg; + + ddsfg.ddsfg_name = ddname; + ddsfg.ddsfg_value = fsid_guid; + + return (dsl_sync_task(ddname, dsl_dataset_set_fsid_guid_check, + dsl_dataset_set_fsid_guid_sync, &ddsfg, 0, + ZFS_SPACE_CHECK_RESERVED)); + }