]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/dsl_prop.c
Unify behavior of deadman parameters
[mirror_zfs.git] / module / zfs / dsl_prop.c
index 0c72dbca53a976a13c58a3101808165d8d887819..57b8eb7941d87f6cdea8b1fe112eb853cce2d431 100644 (file)
@@ -20,8 +20,9 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
  * Copyright (c) 2013 Martin Matuska. All rights reserved.
+ * Copyright 2015, Joyent, Inc.
  */
 
 #include <sys/zfs_context.h>
 #define        ZPROP_RECVD_SUFFIX "$recvd"
 
 static int
-dodefault(const char *propname, int intsz, int numints, void *buf)
+dodefault(zfs_prop_t prop, int intsz, int numints, void *buf)
 {
-       zfs_prop_t prop;
-
        /*
         * The setonce properties are read-only, BUT they still
         * have a default value that can be used as the initial
         * value.
         */
-       if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL ||
+       if (prop == ZPROP_INVAL ||
            (zfs_prop_readonly(prop) && !zfs_prop_setonce(prop)))
                return (SET_ERROR(ENOENT));
 
@@ -149,7 +148,7 @@ dsl_prop_get_dd(dsl_dir_t *dd, const char *propname,
        }
 
        if (err == ENOENT)
-               err = dodefault(propname, intsz, numints, buf);
+               err = dodefault(prop, intsz, numints, buf);
 
        strfree(inheritstr);
        strfree(recvdstr);
@@ -262,7 +261,7 @@ dsl_prop_fini(dsl_dir_t *dd)
 
        while ((pr = list_remove_head(&dd->dd_props)) != NULL) {
                list_destroy(&pr->pr_cbs);
-               strfree((char *)pr->pr_propname);
+               spa_strfree((char *)pr->pr_propname);
                kmem_free(pr, sizeof (dsl_prop_record_t));
        }
        list_destroy(&dd->dd_props);
@@ -660,7 +659,7 @@ dsl_prop_set_sync_impl(dsl_dataset_t *ds, const char *propname,
        int err;
        uint64_t version = spa_version(ds->ds_dir->dd_pool->dp_spa);
 
-       isint = (dodefault(propname, 8, 1, &intval) == 0);
+       isint = (dodefault(zfs_name_to_prop(propname), 8, 1, &intval) == 0);
 
        if (ds->ds_is_snapshot) {
                ASSERT(version >= SPA_VERSION_SNAP_PROPS);
@@ -872,7 +871,7 @@ dsl_props_set_check(void *arg, dmu_tx_t *tx)
                            SPA_VERSION_STMF_PROP ?
                            ZAP_OLDMAXVALUELEN : ZAP_MAXVALUELEN)) {
                                dsl_dataset_rele(ds, FTAG);
-                               return (E2BIG);
+                               return (SET_ERROR(E2BIG));
                        }
                }
        }
@@ -893,11 +892,15 @@ dsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
 
        while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
                nvpair_t *pair = elem;
+               const char *name = nvpair_name(pair);
 
                if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
                        /*
-                        * dsl_prop_get_all_impl() returns properties in this
-                        * format.
+                        * This usually happens when we reuse the nvlist_t data
+                        * returned by the counterpart dsl_prop_get_all_impl().
+                        * For instance we do this to restore the original
+                        * received properties when an error occurs in the
+                        * zfs_ioc_recv() codepath.
                         */
                        nvlist_t *attrs = fnvpair_value_nvlist(pair);
                        pair = fnvlist_lookup_nvpair(attrs, ZPROP_VALUE);
@@ -905,14 +908,14 @@ dsl_props_set_sync_impl(dsl_dataset_t *ds, zprop_source_t source,
 
                if (nvpair_type(pair) == DATA_TYPE_STRING) {
                        const char *value = fnvpair_value_string(pair);
-                       dsl_prop_set_sync_impl(ds, nvpair_name(pair),
+                       dsl_prop_set_sync_impl(ds, name,
                            source, 1, strlen(value) + 1, value, tx);
                } else if (nvpair_type(pair) == DATA_TYPE_UINT64) {
                        uint64_t intval = fnvpair_value_uint64(pair);
-                       dsl_prop_set_sync_impl(ds, nvpair_name(pair),
+                       dsl_prop_set_sync_impl(ds, name,
                            source, sizeof (intval), 1, &intval, tx);
                } else if (nvpair_type(pair) == DATA_TYPE_BOOLEAN) {
-                       dsl_prop_set_sync_impl(ds, nvpair_name(pair),
+                       dsl_prop_set_sync_impl(ds, name,
                            source, 0, 0, NULL, tx);
                } else {
                        panic("invalid nvpair type");
@@ -960,7 +963,7 @@ typedef enum dsl_prop_getflags {
        DSL_PROP_GET_INHERITING = 0x1,  /* searching parent of target ds */
        DSL_PROP_GET_SNAPSHOT = 0x2,    /* snapshot dataset */
        DSL_PROP_GET_LOCAL = 0x4,       /* local properties */
-       DSL_PROP_GET_RECEIVED = 0x8     /* received properties */
+       DSL_PROP_GET_RECEIVED = 0x8,    /* received properties */
 } dsl_prop_getflags_t;
 
 static int
@@ -1096,7 +1099,7 @@ dsl_prop_get_all_ds(dsl_dataset_t *ds, nvlist_t **nvp,
        dsl_pool_t *dp = dd->dd_pool;
        objset_t *mos = dp->dp_meta_objset;
        int err = 0;
-       char setpoint[MAXNAMELEN];
+       char setpoint[ZFS_MAX_DATASET_NAME_LEN];
 
        VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
 
@@ -1127,7 +1130,12 @@ dsl_prop_get_all_ds(dsl_dataset_t *ds, nvlist_t **nvp,
                if (err)
                        break;
        }
+
 out:
+       if (err) {
+               nvlist_free(*nvp);
+               *nvp = NULL;
+       }
        return (err);
 }
 
@@ -1218,7 +1226,7 @@ dsl_prop_nvlist_add_uint64(nvlist_t *nv, zfs_prop_t prop, uint64_t value)
        VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
        VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, value) == 0);
        /* Indicate the default source if we can. */
-       if (dodefault(propname, 8, 1, &default_value) == 0 &&
+       if (dodefault(prop, 8, 1, &default_value) == 0 &&
            value == default_value) {
                VERIFY(nvlist_add_string(propval, ZPROP_SOURCE, "") == 0);
        }