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 <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Akash B <akash-b@hpe.com>
Signed-off-by: Rob Norris <rob.norris@truenas.com>
Closes #18516
This commit is contained in:
Rob Norris
2026-05-09 20:33:26 +10:00
committed by Brian Behlendorf
parent 8ff64005a2
commit bb304d33bb
2 changed files with 249 additions and 167 deletions
+123 -70
View File
@@ -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
}
+126 -97
View File
@@ -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 <sys/zfs_context.h>
@@ -36,6 +37,8 @@
#include <sys/zap_impl.h>
#include <sys/zap_leaf.h>
/* 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)