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,10 +1796,12 @@
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,5 +3505,73 @@
{
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));
+}