Register correct handlers in nvlist_alloc()
[zfs.git] / module / nvpair / nvpair.c
index 77891bf..36f4e4d 100644 (file)
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident  "%Z%%M% %I%     %E% SMI"
-
 #include <sys/stropts.h>
 #include <sys/debug.h>
 #include <sys/isa_defs.h>
@@ -259,6 +256,12 @@ nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv)
        nvl->nvl_pad = 0;
 }
 
+uint_t
+nvlist_nvflag(nvlist_t *nvl)
+{
+       return (nvl->nvl_nvflag);
+}
+
 /*
  * nvlist_alloc - Allocate nvlist.
  */
@@ -266,12 +269,25 @@ nvlist_init(nvlist_t *nvl, uint32_t nvflag, nvpriv_t *priv)
 int
 nvlist_alloc(nvlist_t **nvlp, uint_t nvflag, int kmflag)
 {
+       nv_alloc_t *nva = nv_alloc_nosleep;
+
 #if defined(_KERNEL) && !defined(_BOOT)
-       return (nvlist_xalloc(nvlp, nvflag,
-           (kmflag == KM_SLEEP ? nv_alloc_sleep : nv_alloc_nosleep)));
-#else
-       return (nvlist_xalloc(nvlp, nvflag, nv_alloc_nosleep));
+       switch (kmflag) {
+       case KM_SLEEP:
+               nva = nv_alloc_sleep;
+               break;
+       case KM_PUSHPAGE:
+               nva = nv_alloc_pushpage;
+               break;
+       case KM_NOSLEEP:
+               nva = nv_alloc_nosleep;
+               break;
+       default:
+               return (EINVAL);
+       }
 #endif
+
+       return (nvlist_xalloc(nvlp, nvflag, nva));
 }
 
 int
@@ -692,6 +708,18 @@ nvlist_remove(nvlist_t *nvl, const char *name, data_type_t type)
        return (ENOENT);
 }
 
+int
+nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
+{
+       if (nvl == NULL || nvp == NULL)
+               return (EINVAL);
+
+       nvp_buf_unlink(nvl, nvp);
+       nvpair_free(nvp);
+       nvp_buf_free(nvl, nvp);
+       return (0);
+}
+
 /*
  * This function calculates the size of an nvpair value.
  *
@@ -1162,6 +1190,42 @@ nvlist_next_nvpair(nvlist_t *nvl, nvpair_t *nvp)
        return (curr != NULL ? &curr->nvi_nvp : NULL);
 }
 
+nvpair_t *
+nvlist_prev_nvpair(nvlist_t *nvl, nvpair_t *nvp)
+{
+       nvpriv_t *priv;
+       i_nvp_t *curr;
+
+       if (nvl == NULL ||
+           (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+               return (NULL);
+
+       curr = NVPAIR2I_NVP(nvp);
+
+       if (nvp == NULL)
+               curr = priv->nvp_last;
+       else if (priv->nvp_curr == curr || nvlist_contains_nvp(nvl, nvp))
+               curr = curr->nvi_prev;
+       else
+               curr = NULL;
+
+       priv->nvp_curr = curr;
+
+       return (curr != NULL ? &curr->nvi_nvp : NULL);
+}
+
+boolean_t
+nvlist_empty(nvlist_t *nvl)
+{
+       nvpriv_t *priv;
+
+       if (nvl == NULL ||
+           (priv = (nvpriv_t *)(uintptr_t)nvl->nvl_priv) == NULL)
+               return (B_TRUE);
+
+       return (priv->nvp_list == NULL);
+}
+
 char *
 nvpair_name(nvpair_t *nvp)
 {
@@ -1560,10 +1624,10 @@ nvlist_lookup_nvpair_ei_sep(nvlist_t *nvl, const char *name, const char sep,
 {
        nvpair_t        *nvp;
        const char      *np;
-       char            *sepp;
+       char            *sepp=NULL;
        char            *idxp, *idxep;
        nvlist_t        **nva;
-       long            idx;
+       long            idx = 0;
        int             n;
 
        if (ip)
@@ -2331,7 +2395,7 @@ nvlist_xpack(nvlist_t *nvl, char **bufp, size_t *buflen, int encoding,
         */
        nv_priv_init(&nvpriv, nva, 0);
 
-       if (err = nvlist_size(nvl, &alloc_size, encoding))
+       if ((err = nvlist_size(nvl, &alloc_size, encoding)))
                return (err);
 
        if ((buf = nv_mem_zalloc(&nvpriv, alloc_size)) == NULL)
@@ -3244,3 +3308,131 @@ nvs_xdr(nvstream_t *nvs, nvlist_t *nvl, char *buf, size_t *buflen)
 
        return (err);
 }
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+
+static int nvpair_init(void) { return 0; }
+static int nvpair_fini(void) { return 0; }
+
+spl_module_init(nvpair_init);
+spl_module_exit(nvpair_fini);
+
+MODULE_DESCRIPTION("Generic name/value pair implementation");
+MODULE_AUTHOR(ZFS_META_AUTHOR);
+MODULE_LICENSE(ZFS_META_LICENSE);
+
+EXPORT_SYMBOL(nv_alloc_init);
+EXPORT_SYMBOL(nv_alloc_reset);
+EXPORT_SYMBOL(nv_alloc_fini);
+
+/* list management */
+EXPORT_SYMBOL(nvlist_alloc);
+EXPORT_SYMBOL(nvlist_free);
+EXPORT_SYMBOL(nvlist_size);
+EXPORT_SYMBOL(nvlist_pack);
+EXPORT_SYMBOL(nvlist_unpack);
+EXPORT_SYMBOL(nvlist_dup);
+EXPORT_SYMBOL(nvlist_merge);
+
+EXPORT_SYMBOL(nvlist_xalloc);
+EXPORT_SYMBOL(nvlist_xpack);
+EXPORT_SYMBOL(nvlist_xunpack);
+EXPORT_SYMBOL(nvlist_xdup);
+EXPORT_SYMBOL(nvlist_lookup_nv_alloc);
+
+EXPORT_SYMBOL(nvlist_add_nvpair);
+EXPORT_SYMBOL(nvlist_add_boolean);
+EXPORT_SYMBOL(nvlist_add_boolean_value);
+EXPORT_SYMBOL(nvlist_add_byte);
+EXPORT_SYMBOL(nvlist_add_int8);
+EXPORT_SYMBOL(nvlist_add_uint8);
+EXPORT_SYMBOL(nvlist_add_int16);
+EXPORT_SYMBOL(nvlist_add_uint16);
+EXPORT_SYMBOL(nvlist_add_int32);
+EXPORT_SYMBOL(nvlist_add_uint32);
+EXPORT_SYMBOL(nvlist_add_int64);
+EXPORT_SYMBOL(nvlist_add_uint64);
+EXPORT_SYMBOL(nvlist_add_string);
+EXPORT_SYMBOL(nvlist_add_nvlist);
+EXPORT_SYMBOL(nvlist_add_boolean_array);
+EXPORT_SYMBOL(nvlist_add_byte_array);
+EXPORT_SYMBOL(nvlist_add_int8_array);
+EXPORT_SYMBOL(nvlist_add_uint8_array);
+EXPORT_SYMBOL(nvlist_add_int16_array);
+EXPORT_SYMBOL(nvlist_add_uint16_array);
+EXPORT_SYMBOL(nvlist_add_int32_array);
+EXPORT_SYMBOL(nvlist_add_uint32_array);
+EXPORT_SYMBOL(nvlist_add_int64_array);
+EXPORT_SYMBOL(nvlist_add_uint64_array);
+EXPORT_SYMBOL(nvlist_add_string_array);
+EXPORT_SYMBOL(nvlist_add_nvlist_array);
+EXPORT_SYMBOL(nvlist_next_nvpair);
+EXPORT_SYMBOL(nvlist_prev_nvpair);
+EXPORT_SYMBOL(nvlist_empty);
+EXPORT_SYMBOL(nvlist_add_hrtime);
+
+EXPORT_SYMBOL(nvlist_remove);
+EXPORT_SYMBOL(nvlist_remove_nvpair);
+EXPORT_SYMBOL(nvlist_remove_all);
+
+EXPORT_SYMBOL(nvlist_lookup_boolean);
+EXPORT_SYMBOL(nvlist_lookup_boolean_value);
+EXPORT_SYMBOL(nvlist_lookup_byte);
+EXPORT_SYMBOL(nvlist_lookup_int8);
+EXPORT_SYMBOL(nvlist_lookup_uint8);
+EXPORT_SYMBOL(nvlist_lookup_int16);
+EXPORT_SYMBOL(nvlist_lookup_uint16);
+EXPORT_SYMBOL(nvlist_lookup_int32);
+EXPORT_SYMBOL(nvlist_lookup_uint32);
+EXPORT_SYMBOL(nvlist_lookup_int64);
+EXPORT_SYMBOL(nvlist_lookup_uint64);
+EXPORT_SYMBOL(nvlist_lookup_string);
+EXPORT_SYMBOL(nvlist_lookup_nvlist);
+EXPORT_SYMBOL(nvlist_lookup_boolean_array);
+EXPORT_SYMBOL(nvlist_lookup_byte_array);
+EXPORT_SYMBOL(nvlist_lookup_int8_array);
+EXPORT_SYMBOL(nvlist_lookup_uint8_array);
+EXPORT_SYMBOL(nvlist_lookup_int16_array);
+EXPORT_SYMBOL(nvlist_lookup_uint16_array);
+EXPORT_SYMBOL(nvlist_lookup_int32_array);
+EXPORT_SYMBOL(nvlist_lookup_uint32_array);
+EXPORT_SYMBOL(nvlist_lookup_int64_array);
+EXPORT_SYMBOL(nvlist_lookup_uint64_array);
+EXPORT_SYMBOL(nvlist_lookup_string_array);
+EXPORT_SYMBOL(nvlist_lookup_nvlist_array);
+EXPORT_SYMBOL(nvlist_lookup_hrtime);
+EXPORT_SYMBOL(nvlist_lookup_pairs);
+
+EXPORT_SYMBOL(nvlist_lookup_nvpair);
+EXPORT_SYMBOL(nvlist_exists);
+
+/* processing nvpair */
+EXPORT_SYMBOL(nvpair_name);
+EXPORT_SYMBOL(nvpair_type);
+EXPORT_SYMBOL(nvpair_value_boolean_value);
+EXPORT_SYMBOL(nvpair_value_byte);
+EXPORT_SYMBOL(nvpair_value_int8);
+EXPORT_SYMBOL(nvpair_value_uint8);
+EXPORT_SYMBOL(nvpair_value_int16);
+EXPORT_SYMBOL(nvpair_value_uint16);
+EXPORT_SYMBOL(nvpair_value_int32);
+EXPORT_SYMBOL(nvpair_value_uint32);
+EXPORT_SYMBOL(nvpair_value_int64);
+EXPORT_SYMBOL(nvpair_value_uint64);
+EXPORT_SYMBOL(nvpair_value_string);
+EXPORT_SYMBOL(nvpair_value_nvlist);
+EXPORT_SYMBOL(nvpair_value_boolean_array);
+EXPORT_SYMBOL(nvpair_value_byte_array);
+EXPORT_SYMBOL(nvpair_value_int8_array);
+EXPORT_SYMBOL(nvpair_value_uint8_array);
+EXPORT_SYMBOL(nvpair_value_int16_array);
+EXPORT_SYMBOL(nvpair_value_uint16_array);
+EXPORT_SYMBOL(nvpair_value_int32_array);
+EXPORT_SYMBOL(nvpair_value_uint32_array);
+EXPORT_SYMBOL(nvpair_value_int64_array);
+EXPORT_SYMBOL(nvpair_value_uint64_array);
+EXPORT_SYMBOL(nvpair_value_string_array);
+EXPORT_SYMBOL(nvpair_value_nvlist_array);
+EXPORT_SYMBOL(nvpair_value_hrtime);
+
+#endif