From bb304d33bb5d7f027487c4635fd7ed35aa52ba65 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 9 May 2026 20:33:26 +1000 Subject: [PATCH] zap: public interface cleanup - reorganising functions into groups, collections of the variants of the same function. - matching header order to source order, to make it a little easier to find things. - moving per-function documentation from source to header. - adding light documentation to functions that had none. No actual code changes. Sponsored-by: TrueNAS Reviewed-by: Brian Behlendorf Reviewed-by: Tony Hutter Reviewed-by: Akash B Signed-off-by: Rob Norris Closes #18516 --- include/sys/zap.h | 193 ++++++++++++++++++++++++--------------- module/zfs/zap.c | 223 ++++++++++++++++++++++++++-------------------- 2 files changed, 249 insertions(+), 167 deletions(-) diff --git a/include/sys/zap.h b/include/sys/zap.h index 66fbc1385d2..69f021034ba 100644 --- a/include/sys/zap.h +++ b/include/sys/zap.h @@ -24,6 +24,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2018 by Delphix. All rights reserved. * Copyright 2017 Nexenta Systems, Inc. + * Copyright (c) 2026, TrueNAS. */ #ifndef _SYS_ZAP_H @@ -121,13 +122,13 @@ typedef enum zap_flags { /* * Create a new zapobj with no attributes and return its object number. */ -uint64_t zap_create(objset_t *ds, dmu_object_type_t ot, +uint64_t zap_create(objset_t *os, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx); -uint64_t zap_create_dnsize(objset_t *ds, dmu_object_type_t ot, +uint64_t zap_create_dnsize(objset_t *os, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx); -uint64_t zap_create_norm(objset_t *ds, int normflags, dmu_object_type_t ot, +uint64_t zap_create_norm(objset_t *os, int normflags, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx); -uint64_t zap_create_norm_dnsize(objset_t *ds, int normflags, +uint64_t zap_create_norm_dnsize(objset_t *os, int normflags, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx); uint64_t zap_create_flags(objset_t *os, int normflags, zap_flags_t flags, @@ -137,11 +138,22 @@ uint64_t zap_create_flags_dnsize(objset_t *os, int normflags, zap_flags_t flags, dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift, dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx); + +/* + * Create a zap object and return a pointer to the newly allocated dnode via + * the allocated_dnode argument. The returned dnode will be held and the + * caller is responsible for releasing the hold by calling dnode_rele(). + */ uint64_t zap_create_hold(objset_t *os, int normflags, zap_flags_t flags, dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift, dmu_object_type_t bonustype, int bonuslen, int dnodesize, dnode_t **allocated_dnode, const void *tag, dmu_tx_t *tx); +/* + * Create a new zapobj with no attributes, and add an entry to an existing + * zapobj with the given name as key and the object number of the new zapobj as + * the value. Returns the object number of the new zapobj. + */ uint64_t zap_create_link(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj, const char *name, dmu_tx_t *tx); uint64_t zap_create_link_dnsize(objset_t *os, dmu_object_type_t ot, @@ -157,20 +169,21 @@ void mzap_create_impl(dnode_t *dn, int normflags, zap_flags_t flags, * Create a new zapobj with no attributes from the given (unallocated) * object number. */ -int zap_create_claim(objset_t *ds, uint64_t obj, dmu_object_type_t ot, +int zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx); -int zap_create_claim_dnsize(objset_t *ds, uint64_t obj, dmu_object_type_t ot, +int zap_create_claim_dnsize(objset_t *os, uint64_t obj, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx); -int zap_create_claim_norm(objset_t *ds, uint64_t obj, +int zap_create_claim_norm(objset_t *os, uint64_t obj, int normflags, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx); -int zap_create_claim_norm_dnsize(objset_t *ds, uint64_t obj, +int zap_create_claim_norm_dnsize(objset_t *os, uint64_t obj, int normflags, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, int dnodesize, dmu_tx_t *tx); /* - * The zapobj passed in must be a valid ZAP object for all of the - * following routines. + * All operations on a zapobj take either the the objset/objectid pair + * that "names" the object, or an existing dnode_t for the object. The + * zapobj passed in must be a valid ZAP object. */ /* @@ -178,7 +191,7 @@ int zap_create_claim_norm_dnsize(objset_t *ds, uint64_t obj, * * Frees the object number using dmu_object_free. */ -int zap_destroy(objset_t *ds, uint64_t zapobj, dmu_tx_t *tx); +int zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx); /* * Manipulate attributes. @@ -207,21 +220,32 @@ int zap_destroy(objset_t *ds, uint64_t zapobj, dmu_tx_t *tx); * fit will be transferred to 'buf'. If the entire attribute was not * transferred, the call will return EOVERFLOW. */ -int zap_lookup(objset_t *ds, uint64_t zapobj, const char *name, +int zap_lookup(objset_t *os, uint64_t zapobj, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf); +int zap_lookup_by_dnode(dnode_t *dn, const char *name, uint64_t integer_size, uint64_t num_integers, void *buf); /* * If rn_len is nonzero, realname will be set to the name of the found * entry (which may be different from the requested name if matchtype is - * not MT_EXACT). + * not zero). * * If normalization_conflictp is not NULL, it will be set if there is * another name with the same case/unicode normalized form. */ -int zap_lookup_norm(objset_t *ds, uint64_t zapobj, const char *name, +int zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name, uint64_t integer_size, uint64_t num_integers, void *buf, matchtype_t mt, char *realname, int rn_len, boolean_t *normalization_conflictp); +int zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf, + matchtype_t mt, char *realname, int rn_len, + boolean_t *ncp); + +/* + * The _uint64 variants take an array of uint64_t as the key. The ZAP must + * be created with ZAP_FLAG_UINT64_KEY. + */ int zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf); int zap_lookup_uint64_by_dnode(dnode_t *dn, const uint64_t *key, @@ -229,20 +253,30 @@ int zap_lookup_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int zap_lookup_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf, uint64_t *actual_num_integers); -int zap_contains(objset_t *ds, uint64_t zapobj, const char *name); + +/* + * Lookup the attribute with the given name. Returns ENOENT if it does not + * exist, 0 if it does. This is like zap_lookup(), but may be more efficient. + */ +int zap_contains(objset_t *os, uint64_t zapobj, const char *name); + +/* + * Prefetch the blocks within the ZAP where the given key is stored. The + * prefetch IO will occure in the background. + */ int zap_prefetch(objset_t *os, uint64_t zapobj, const char *name); -int zap_prefetch_object(objset_t *os, uint64_t zapobj); + +/* Prefetch by uint64_t[] key. */ int zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints); int zap_prefetch_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints); -int zap_lookup_by_dnode(dnode_t *dn, const char *name, - uint64_t integer_size, uint64_t num_integers, void *buf); -int zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, - uint64_t integer_size, uint64_t num_integers, void *buf, - matchtype_t mt, char *realname, int rn_len, - boolean_t *ncp); +/* + * Prefetch the entire ZAP object. Unlike zap_prefetch(), will block until + * the entire object is loaded into the ARC. + */ +int zap_prefetch_object(objset_t *os, uint64_t zapobj); /* * Create an attribute with the given name and value. @@ -250,13 +284,15 @@ int zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, * If an attribute with the given name already exists, the call will * fail and return EEXIST. */ -int zap_add(objset_t *ds, uint64_t zapobj, const char *key, +int zap_add(objset_t *os, uint64_t zapobj, const char *key, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); int zap_add_by_dnode(dnode_t *dn, const char *key, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); -int zap_add_uint64(objset_t *ds, uint64_t zapobj, const uint64_t *key, + +/* Add by uint64_t[] key. */ +int zap_add_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); int zap_add_uint64_by_dnode(dnode_t *dn, const uint64_t *key, @@ -271,8 +307,10 @@ int zap_add_uint64_by_dnode(dnode_t *dn, const uint64_t *key, * existing attribute's integer size, in which case the attribute's * integer size will be updated to the new value. */ -int zap_update(objset_t *ds, uint64_t zapobj, const char *name, +int zap_update(objset_t *os, uint64_t zapobj, const char *name, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); + +/* Update by uint64_t[] key. */ int zap_update_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx); @@ -287,8 +325,10 @@ int zap_update_uint64_by_dnode(dnode_t *dn, const uint64_t *key, * If the requested attribute does not exist, the call will fail and * return ENOENT. */ -int zap_length(objset_t *ds, uint64_t zapobj, const char *name, +int zap_length(objset_t *os, uint64_t zapobj, const char *name, uint64_t *integer_size, uint64_t *num_integers); + +/* Attribute length by uint64_t[] key. */ int zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, uint64_t *integer_size, uint64_t *num_integers); int zap_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key, @@ -300,10 +340,12 @@ int zap_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key, * If the specified attribute does not exist, the call will fail and * return ENOENT. */ -int zap_remove(objset_t *ds, uint64_t zapobj, const char *name, dmu_tx_t *tx); -int zap_remove_norm(objset_t *ds, uint64_t zapobj, const char *name, - matchtype_t mt, dmu_tx_t *tx); +int zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx); int zap_remove_by_dnode(dnode_t *dn, const char *name, dmu_tx_t *tx); +int zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name, + matchtype_t mt, dmu_tx_t *tx); + +/* Remove by uint64_t[] key. */ int zap_remove_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, dmu_tx_t *tx); int zap_remove_uint64_by_dnode(dnode_t *dn, const uint64_t *key, @@ -313,9 +355,17 @@ int zap_remove_uint64_by_dnode(dnode_t *dn, const uint64_t *key, * Returns (in *count) the number of attributes in the specified zap * object. */ -int zap_count(objset_t *ds, uint64_t zapobj, uint64_t *count); +int zap_count(objset_t *os, uint64_t zapobj, uint64_t *count); int zap_count_by_dnode(dnode_t *dn, uint64_t *count); +/* + * Lookup an existing uint64 value, add the delta value to it, and store + * update it with the new value. If the new value is 0, removes the key + * entirely. + */ +int zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta, + dmu_tx_t *tx); + /* * Returns (in name) the name of the entry whose (value & mask) * (za_first_integer) is value, or ENOENT if not found. The string @@ -358,22 +408,12 @@ int zap_update_int_key(objset_t *os, uint64_t obj, int zap_lookup_int_key(objset_t *os, uint64_t obj, uint64_t key, uint64_t *valuep); -int zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta, - dmu_tx_t *tx); - -struct zap; -struct zap_leaf; -typedef struct zap_cursor { - /* This structure is opaque! */ - objset_t *zc_objset; - struct zap *zc_zap; - struct zap_leaf *zc_leaf; - uint64_t zc_zapobj; - uint64_t zc_serialized; - uint64_t zc_hash; - uint32_t zc_cd; - boolean_t zc_prefetch; -} zap_cursor_t; +/* + * The interface for listing all the attributes of a zapobj can be + * thought of as cursor moving down a list of the attributes one by + * one. The cookie returned by the zap_cursor_serialize routine is + * persistent across system calls (and across reboot, even). + */ typedef struct { int za_integer_length; @@ -389,9 +429,6 @@ typedef struct { char za_name[]; } zap_attribute_t; -void zap_init(void); -void zap_fini(void); - /* * Alloc and free zap_attribute_t. */ @@ -399,21 +436,44 @@ zap_attribute_t *zap_attribute_alloc(void); zap_attribute_t *zap_attribute_long_alloc(void); void zap_attribute_free(zap_attribute_t *attrp); -/* - * The interface for listing all the attributes of a zapobj can be - * thought of as cursor moving down a list of the attributes one by - * one. The cookie returned by the zap_cursor_serialize routine is - * persistent across system calls (and across reboot, even). - */ +struct zap; +struct zap_leaf; +typedef struct zap_cursor { + /* This structure is opaque! */ + objset_t *zc_objset; + struct zap *zc_zap; + struct zap_leaf *zc_leaf; + uint64_t zc_zapobj; + uint64_t zc_serialized; + uint64_t zc_hash; + uint32_t zc_cd; + boolean_t zc_prefetch; +} zap_cursor_t; /* - * Initialize a zap cursor, pointing to the "first" attribute of the - * zapobj. You must _fini the cursor when you are done with it. + * Initialize a zap cursor, pointing to the "first" attribute of the zapobj. + * The entire zapobj will be prefetched. You must call zap_cursor_fini the + * cursor when you are done with it. */ void zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj); +void zap_cursor_fini(zap_cursor_t *zc); + +/* + * Initialize a cursor at the beginning, but request that we not prefetch + * the entire ZAP object. + */ void zap_cursor_init_noprefetch(zap_cursor_t *zc, objset_t *os, uint64_t zapobj); -void zap_cursor_fini(zap_cursor_t *zc); + +/* + * Initialize a zap cursor pointing to the position recorded by + * zap_cursor_serialize (in the "serialized" argument). You can also + * use a "serialized" argument of 0 to start at the beginning of the + * zapobj (ie. zap_cursor_init_serialized(..., 0) is equivalent to + * zap_cursor_init(...).) + */ +void zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, + uint64_t zapobj, uint64_t serialized); /* * Get the attribute currently pointed to by the cursor. Returns @@ -435,17 +495,6 @@ void zap_cursor_advance(zap_cursor_t *zc); */ uint64_t zap_cursor_serialize(zap_cursor_t *zc); -/* - * Initialize a zap cursor pointing to the position recorded by - * zap_cursor_serialize (in the "serialized" argument). You can also - * use a "serialized" argument of 0 to start at the beginning of the - * zapobj (ie. zap_cursor_init_serialized(..., 0) is equivalent to - * zap_cursor_init(...).) - */ -void zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *ds, - uint64_t zapobj, uint64_t serialized); - - #define ZAP_HISTOGRAM_SIZE 10 typedef struct zap_stats { @@ -535,7 +584,11 @@ typedef struct zap_stats { * statistics. This interface shouldn't be relied on unless you really * know what you're doing. */ -int zap_get_stats(objset_t *ds, uint64_t zapobj, zap_stats_t *zs); +int zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs); + +/* ZAP subsystem setup/teardown */ +void zap_init(void); +void zap_fini(void); #ifdef __cplusplus } diff --git a/module/zfs/zap.c b/module/zfs/zap.c index fa3f8b836c9..4c4aec07c91 100644 --- a/module/zfs/zap.c +++ b/module/zfs/zap.c @@ -26,6 +26,7 @@ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2017 Nexenta Systems, Inc. * Copyright (c) 2024, Klara, Inc. + * Copyright (c) 2026, TrueNAS. */ #include @@ -36,6 +37,8 @@ #include #include +/* zap_create */ + static uint64_t zap_create_impl(objset_t *os, int normflags, zap_flags_t flags, dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift, @@ -113,11 +116,8 @@ zap_create_flags_dnsize(objset_t *os, int normflags, zap_flags_t flags, tx)); } -/* - * Create a zap object and return a pointer to the newly allocated dnode via - * the allocated_dnode argument. The returned dnode will be held and the - * caller is responsible for releasing the hold by calling dnode_rele(). - */ +/* zap_crate_hold */ + uint64_t zap_create_hold(objset_t *os, int normflags, zap_flags_t flags, dmu_object_type_t ot, int leaf_blockshift, int indirect_blockshift, @@ -129,6 +129,8 @@ zap_create_hold(objset_t *os, int normflags, zap_flags_t flags, allocated_dnode, tag, tx)); } +/* zap_create_link */ + uint64_t zap_create_link(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj, const char *name, dmu_tx_t *tx) @@ -150,6 +152,8 @@ zap_create_link_dnsize(objset_t *os, dmu_object_type_t ot, uint64_t parent_obj, return (new_obj); } +/* zap_create_claim */ + int zap_create_claim(objset_t *os, uint64_t obj, dmu_object_type_t ot, dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx) @@ -200,6 +204,8 @@ zap_create_claim_norm_dnsize(objset_t *os, uint64_t obj, int normflags, return (0); } +/* zap_destroy */ + int zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx) { @@ -212,9 +218,7 @@ zap_destroy(objset_t *os, uint64_t zapobj, dmu_tx_t *tx) return (dmu_object_free(os, zapobj, tx)); } -/* - * Routines for manipulating attributes. - */ +/* zap_lookup */ static int zap_lookup_impl(zap_t *zap, const char *name, @@ -267,6 +271,14 @@ zap_lookup(objset_t *os, uint64_t zapobj, const char *name, num_integers, buf, 0, NULL, 0, NULL)); } +int +zap_lookup_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf) +{ + return (zap_lookup_norm_by_dnode(dn, name, integer_size, + num_integers, buf, 0, NULL, 0, NULL)); +} + int zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name, uint64_t integer_size, uint64_t num_integers, void *buf, @@ -285,6 +297,26 @@ zap_lookup_norm(objset_t *os, uint64_t zapobj, const char *name, return (err); } +int +zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, + uint64_t integer_size, uint64_t num_integers, void *buf, + matchtype_t mt, char *realname, int rn_len, + boolean_t *ncp) +{ + zap_t *zap; + + int err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, + FTAG, &zap); + if (err != 0) + return (err); + err = zap_lookup_impl(zap, name, integer_size, + num_integers, buf, mt, realname, rn_len, ncp); + zap_unlockdir(zap, FTAG); + return (err); +} + +/* zap_lookup_uint64 */ + static int zap_lookup_length_uint64_impl(zap_t *zap, const uint64_t *key, int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf, @@ -303,7 +335,6 @@ zap_lookup_length_uint64_impl(zap_t *zap, const uint64_t *key, return (err); } - int zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf) @@ -353,6 +384,8 @@ zap_lookup_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key, return (err); } +/* zap_contains */ + int zap_contains(objset_t *os, uint64_t zapobj, const char *name) { @@ -363,6 +396,8 @@ zap_contains(objset_t *os, uint64_t zapobj, const char *name) return (err); } +/* zap_prefetch */ + int zap_prefetch(objset_t *os, uint64_t zapobj, const char *name) { @@ -385,21 +420,7 @@ zap_prefetch(objset_t *os, uint64_t zapobj, const char *name) return (err); } -int -zap_prefetch_object(objset_t *os, uint64_t zapobj) -{ - int error; - dmu_object_info_t doi; - - error = dmu_object_info(os, zapobj, &doi); - if (error == 0 && DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP) - error = SET_ERROR(EINVAL); - if (error == 0) - dmu_prefetch_wait(os, zapobj, 0, doi.doi_max_offset); - - return (error); -} - +/* zap_prefetch_uint64 */ static int zap_prefetch_uint64_impl(zap_t *zap, const uint64_t *key, int key_numints) @@ -445,32 +466,25 @@ zap_prefetch_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints) return (err); } -int -zap_lookup_by_dnode(dnode_t *dn, const char *name, - uint64_t integer_size, uint64_t num_integers, void *buf) -{ - return (zap_lookup_norm_by_dnode(dn, name, integer_size, - num_integers, buf, 0, NULL, 0, NULL)); -} +/* zap_prefetch_object */ int -zap_lookup_norm_by_dnode(dnode_t *dn, const char *name, - uint64_t integer_size, uint64_t num_integers, void *buf, - matchtype_t mt, char *realname, int rn_len, - boolean_t *ncp) +zap_prefetch_object(objset_t *os, uint64_t zapobj) { - zap_t *zap; + int error; + dmu_object_info_t doi; - int err = zap_lockdir_by_dnode(dn, NULL, RW_READER, TRUE, FALSE, - FTAG, &zap); - if (err != 0) - return (err); - err = zap_lookup_impl(zap, name, integer_size, - num_integers, buf, mt, realname, rn_len, ncp); - zap_unlockdir(zap, FTAG); - return (err); + error = dmu_object_info(os, zapobj, &doi); + if (error == 0 && DMU_OT_BYTESWAP(doi.doi_type) != DMU_BSWAP_ZAP) + error = SET_ERROR(EINVAL); + if (error == 0) + dmu_prefetch_wait(os, zapobj, 0, doi.doi_max_offset); + + return (error); } +/* zap_add */ + static int zap_add_impl(zap_t *zap, const char *key, int integer_size, uint64_t num_integers, @@ -543,6 +557,8 @@ zap_add_by_dnode(dnode_t *dn, const char *key, return (err); } +/* zap_add_uint64 */ + static int zap_add_uint64_impl(zap_t *zap, const uint64_t *key, int key_numints, int integer_size, uint64_t num_integers, @@ -597,6 +613,8 @@ zap_add_uint64_by_dnode(dnode_t *dn, const uint64_t *key, return (err); } +/* zap_update */ + int zap_update(objset_t *os, uint64_t zapobj, const char *name, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx) @@ -644,6 +662,8 @@ zap_update(objset_t *os, uint64_t zapobj, const char *name, return (err); } +/* zap_update_uint64 */ + static int zap_update_uint64_impl(zap_t *zap, const uint64_t *key, int key_numints, int integer_size, uint64_t num_integers, const void *val, dmu_tx_t *tx, @@ -697,6 +717,8 @@ zap_update_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints, return (err); } +/* zap_length */ + int zap_length(objset_t *os, uint64_t zapobj, const char *name, uint64_t *integer_size, uint64_t *num_integers) @@ -731,6 +753,8 @@ zap_length(objset_t *os, uint64_t zapobj, const char *name, return (err); } +/* zap_length_uint64 */ + int zap_length_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key, int key_numints, uint64_t *integer_size, uint64_t *num_integers) @@ -773,6 +797,8 @@ zap_length_uint64_by_dnode(dnode_t *dn, const uint64_t *key, return (err); } +/* zap_remove */ + static int zap_remove_impl(zap_t *zap, const char *name, matchtype_t mt, dmu_tx_t *tx) @@ -805,6 +831,20 @@ zap_remove(objset_t *os, uint64_t zapobj, const char *name, dmu_tx_t *tx) return (zap_remove_norm(os, zapobj, name, 0, tx)); } +int +zap_remove_by_dnode(dnode_t *dn, const char *name, dmu_tx_t *tx) +{ + zap_t *zap; + int err; + + err = zap_lockdir_by_dnode(dn, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap); + if (err) + return (err); + err = zap_remove_impl(zap, name, 0, tx); + zap_unlockdir(zap, FTAG); + return (err); +} + int zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name, matchtype_t mt, dmu_tx_t *tx) @@ -820,19 +860,7 @@ zap_remove_norm(objset_t *os, uint64_t zapobj, const char *name, return (err); } -int -zap_remove_by_dnode(dnode_t *dn, const char *name, dmu_tx_t *tx) -{ - zap_t *zap; - int err; - - err = zap_lockdir_by_dnode(dn, tx, RW_WRITER, TRUE, FALSE, FTAG, &zap); - if (err) - return (err); - err = zap_remove_impl(zap, name, 0, tx); - zap_unlockdir(zap, FTAG); - return (err); -} +/* zap_remove_uint64 */ static int zap_remove_uint64_impl(zap_t *zap, const uint64_t *key, int key_numints, @@ -881,6 +909,8 @@ zap_remove_uint64_by_dnode(dnode_t *dn, const uint64_t *key, int key_numints, return (err); } +/* zap_count */ + int zap_count(objset_t *os, uint64_t zapobj, uint64_t *count) { @@ -917,9 +947,29 @@ zap_count_by_dnode(dnode_t *dn, uint64_t *count) return (err); } -/* - * Helper functions for consumers. - */ +/* zap_increment */ + +int +zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta, + dmu_tx_t *tx) +{ + uint64_t value = 0; + + if (delta == 0) + return (0); + + int err = zap_lookup(os, obj, name, 8, 1, &value); + if (err != 0 && err != ENOENT) + return (err); + value += delta; + if (value == 0) + err = zap_remove(os, obj, name, tx); + else + err = zap_update(os, obj, name, 8, 1, &value, tx); + return (err); +} + +/* zap_value_search */ int zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask, @@ -946,6 +996,8 @@ zap_value_search(objset_t *os, uint64_t zapobj, uint64_t value, uint64_t mask, return (err); } +/* zap_join */ + int zap_join(objset_t *os, uint64_t fromobj, uint64_t intoobj, dmu_tx_t *tx) { @@ -1025,6 +1077,9 @@ zap_join_increment(objset_t *os, uint64_t fromobj, uint64_t intoobj, zap_attribute_free(za); return (err); } + +/* zap_*_int */ + int zap_add_int(objset_t *os, uint64_t obj, uint64_t value, dmu_tx_t *tx) { @@ -1062,6 +1117,8 @@ zap_increment_int(objset_t *os, uint64_t obj, uint64_t key, int64_t delta, return (zap_increment(os, obj, name, delta, tx)); } +/* zap_*_int_key */ + int zap_add_int_key(objset_t *os, uint64_t obj, uint64_t key, uint64_t value, dmu_tx_t *tx) @@ -1091,29 +1148,7 @@ zap_lookup_int_key(objset_t *os, uint64_t obj, uint64_t key, uint64_t *valuep) return (zap_lookup(os, obj, name, 8, 1, valuep)); } -int -zap_increment(objset_t *os, uint64_t obj, const char *name, int64_t delta, - dmu_tx_t *tx) -{ - uint64_t value = 0; - - if (delta == 0) - return (0); - - int err = zap_lookup(os, obj, name, 8, 1, &value); - if (err != 0 && err != ENOENT) - return (err); - value += delta; - if (value == 0) - err = zap_remove(os, obj, name, tx); - else - err = zap_update(os, obj, name, 8, 1, &value, tx); - return (err); -} - -/* - * Routines for iterating over the attributes. - */ +/* zap_cursor */ static void zap_cursor_init_impl(zap_cursor_t *zc, objset_t *os, uint64_t zapobj, @@ -1129,26 +1164,25 @@ zap_cursor_init_impl(zap_cursor_t *zc, objset_t *os, uint64_t zapobj, zc->zc_prefetch = prefetch; } -/* - * Initialize a cursor at the beginning of the ZAP object. The entire - * ZAP object will be prefetched. - */ void zap_cursor_init(zap_cursor_t *zc, objset_t *os, uint64_t zapobj) { zap_cursor_init_impl(zc, os, zapobj, 0, B_TRUE); } -/* - * Initialize a cursor at the beginning, but request that we not prefetch - * the entire ZAP object. - */ void zap_cursor_init_noprefetch(zap_cursor_t *zc, objset_t *os, uint64_t zapobj) { zap_cursor_init_impl(zc, os, zapobj, 0, B_FALSE); } +void +zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj, + uint64_t serialized) +{ + zap_cursor_init_impl(zc, os, zapobj, serialized, B_TRUE); +} + void zap_cursor_fini(zap_cursor_t *zc) { @@ -1262,12 +1296,7 @@ zap_cursor_serialize(zap_cursor_t *zc) ((uint64_t)zc->zc_cd << zap_hashbits(zc->zc_zap))); } -void -zap_cursor_init_serialized(zap_cursor_t *zc, objset_t *os, uint64_t zapobj, - uint64_t serialized) -{ - zap_cursor_init_impl(zc, os, zapobj, serialized, B_TRUE); -} +/* zap_get_stats */ int zap_get_stats(objset_t *os, uint64_t zapobj, zap_stats_t *zs)