From 00a941ea093737950b8e5aa14a1c45ec4848be7d Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sat, 9 May 2026 22:19:23 +1000 Subject: [PATCH] zap: internal interface cleanup Similar to previous, though a much lighter touch because these are not "public" interfaces. - reorganising functions into groups, by rough function class. - matching header order to source order, to make it a little easier to find things. - adding light documentation to functions that had none. Note that I've not added any documentation for the mzap_* and fzap_* functions, as part of this commit series is laying the groundwork to hide those functions in their backend modules; such documentation would become obsolete very quickly. 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_impl.h | 77 ++++-- module/zfs/zap_impl.c | 519 +++++++++++++++++++++-------------------- 2 files changed, 325 insertions(+), 271 deletions(-) diff --git a/include/sys/zap_impl.h b/include/sys/zap_impl.h index 78c57e522bc..15cc96df3d1 100644 --- a/include/sys/zap_impl.h +++ b/include/sys/zap_impl.h @@ -26,6 +26,7 @@ * Copyright (c) 2013, 2016 by Delphix. All rights reserved. * Copyright 2017 Nexenta Systems, Inc. * Copyright (c) 2024, Klara, Inc. + * Copyright (c) 2026, TrueNAS. */ #ifndef _SYS_ZAP_IMPL_H @@ -33,7 +34,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -170,6 +170,9 @@ typedef struct zap { } zap_u; } zap_t; +#define zap_f zap_u.zap_fat +#define zap_m zap_u.zap_micro + static inline zap_phys_t * zap_f_phys(zap_t *zap) { @@ -182,6 +185,10 @@ zap_m_phys(zap_t *zap) return (zap->zap_dbuf->db_data); } +/* + * zap_name_t carries the original key and whatever we've derived from it + * (normalised form, hash, etc) as we work through completing the operation. + */ typedef struct zap_name { zap_t *zn_zap; int zn_key_intlen; @@ -196,35 +203,74 @@ typedef struct zap_name { char zn_normbuf[]; } zap_name_t; -#define zap_f zap_u.zap_fat -#define zap_m zap_u.zap_micro +/* + * Allocate a zap_name_t. The longname flag ensures there is enough room to + * hold a long filename when the 'longname' pool feature is active. + */ +zap_name_t *zap_name_alloc(zap_t *zap, boolean_t longname); +/* + * Allocate a zap_name_t for the given key. zap_name_init_str() will be + * called to normalise the key and initialise the struct. + */ +zap_name_t *zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt); + +/* + * Allocate a zap_name_t for a uint64 array key. + */ +zap_name_t *zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints); + +/* + * Free a zap_name_t. + */ +void zap_name_free(zap_name_t *zn); + +/* + * Initialise an existing zap_name_t with the normalised form of the key, + * computed according to the given matchtype. + */ +int zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt); + +/* + * Compare 'matchname' with the name represented by the zap_name_t, applying + * the same normalisation method first. Returns true if the normalised forms + * match, false otherwise. + */ boolean_t zap_match(zap_name_t *zn, const char *matchname); + +/* + * Compute and return the 64-bit hash for the name, according to the name + * type and hash flags. + */ +uint64_t zap_hash(zap_name_t *zn); + +/* + * Return a zap_t for the given on-disk object, locked and ready for use. + * The zap_t will be allocated and loaded from disk if its not already loaded. + */ int zap_lockdir(objset_t *os, uint64_t obj, dmu_tx_t *tx, krw_t lti, boolean_t fatreader, boolean_t adding, const void *tag, zap_t **zapp); int zap_lockdir_by_dnode(dnode_t *dn, dmu_tx_t *tx, krw_t lti, boolean_t fatreader, boolean_t adding, const void *tag, zap_t **zapp); + +/* Underlying implementation for above; do not use. */ int zap_lockdir_impl(dnode_t *dn, dmu_buf_t *db, const void *tag, dmu_tx_t *tx, krw_t lti, boolean_t fatreader, boolean_t adding, zap_t **zapp); + +/* Unlock and release a zap_t. */ void zap_unlockdir(zap_t *zap, const void *tag); + +/* zap_t release function for when associated dbuf is evicted. */ void zap_evict_sync(void *dbu); -zap_name_t * zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, - int numints); -zap_name_t *zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt); -int zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt); -zap_name_t * zap_name_alloc(zap_t *zap, boolean_t longname); -void zap_name_free(zap_name_t *zn); + +/* Misc internal state & config. */ int zap_hashbits(zap_t *zap); uint32_t zap_maxcd(zap_t *zap); uint64_t zap_getflags(zap_t *zap); -int zap_normalize(zap_t *zap, const char *name, char *namenorm, int normflags, - size_t outlen); -uint64_t zap_hash(zap_name_t *zn); - -uint64_t zap_get_micro_max_size(spa_t *spa); +/* Microzap implementation. */ zap_t *mzap_open(dmu_buf_t *db); int mzap_upgrade(zap_t **zapp, const void *tag, dmu_tx_t *tx, zap_flags_t flags); @@ -235,7 +281,9 @@ boolean_t mzap_normalization_conflict(zap_t *zap, zap_name_t *zn, mzap_ent_t *mze, zfs_btree_index_t *idx); void mzap_addent(zap_name_t *zn, uint64_t value); void mzap_byteswap(mzap_phys_t *buf, size_t size); +uint64_t zap_get_micro_max_size(spa_t *spa); +/* Fatzap implementation. */ void fzap_byteswap(void *buf, size_t size); int fzap_count(zap_t *zap, uint64_t *count); int fzap_lookup(zap_name_t *zn, @@ -254,7 +302,6 @@ int fzap_remove(zap_name_t *zn, dmu_tx_t *tx); int fzap_cursor_retrieve(zap_t *zap, zap_cursor_t *zc, zap_attribute_t *za); void fzap_get_stats(zap_t *zap, zap_stats_t *zs); void zap_put_leaf(struct zap_leaf *l); - int fzap_add_cd(zap_name_t *zn, uint64_t integer_size, uint64_t num_integers, const void *val, uint32_t cd, const void *tag, dmu_tx_t *tx); diff --git a/module/zfs/zap_impl.c b/module/zfs/zap_impl.c index 8788480318f..c70fce67875 100644 --- a/module/zfs/zap_impl.c +++ b/module/zfs/zap_impl.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 @@ -35,6 +36,255 @@ #include #include +static kmem_cache_t *zap_name_cache; +static kmem_cache_t *zap_attr_cache; +static kmem_cache_t *zap_name_long_cache; +static kmem_cache_t *zap_attr_long_cache; + +/* Setup/teardown caches. Part of the public interface in zap.h. */ +void +zap_init(void) +{ + zap_name_cache = kmem_cache_create("zap_name", + sizeof (zap_name_t) + ZAP_MAXNAMELEN, 0, NULL, NULL, + NULL, NULL, NULL, 0); + + zap_attr_cache = kmem_cache_create("zap_attr_cache", + sizeof (zap_attribute_t) + ZAP_MAXNAMELEN, 0, NULL, + NULL, NULL, NULL, NULL, 0); + + zap_name_long_cache = kmem_cache_create("zap_name_long", + sizeof (zap_name_t) + ZAP_MAXNAMELEN_NEW, 0, NULL, NULL, + NULL, NULL, NULL, 0); + + zap_attr_long_cache = kmem_cache_create("zap_attr_long_cache", + sizeof (zap_attribute_t) + ZAP_MAXNAMELEN_NEW, 0, NULL, + NULL, NULL, NULL, NULL, 0); +} + +void +zap_fini(void) +{ + kmem_cache_destroy(zap_name_cache); + kmem_cache_destroy(zap_attr_cache); + kmem_cache_destroy(zap_name_long_cache); + kmem_cache_destroy(zap_attr_long_cache); +} + +static int +zap_normalize(zap_t *zap, const char *name, char *namenorm, int normflags, + size_t outlen) +{ + ASSERT(!(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY)); + + size_t inlen = strlen(name) + 1; + + int err = 0; + (void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen, + normflags | U8_TEXTPREP_IGNORE_NULL | U8_TEXTPREP_IGNORE_INVALID, + U8_UNICODE_LATEST, &err); + + return (err); +} + +zap_name_t * +zap_name_alloc(zap_t *zap, boolean_t longname) +{ + kmem_cache_t *cache = longname ? zap_name_long_cache : zap_name_cache; + zap_name_t *zn = kmem_cache_alloc(cache, KM_SLEEP); + + zn->zn_zap = zap; + zn->zn_normbuf_len = longname ? ZAP_MAXNAMELEN_NEW : ZAP_MAXNAMELEN; + return (zn); +} + +zap_name_t * +zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt) +{ + size_t key_len = strlen(key) + 1; + zap_name_t *zn = zap_name_alloc(zap, (key_len > ZAP_MAXNAMELEN)); + if (zap_name_init_str(zn, key, mt) != 0) { + zap_name_free(zn); + return (NULL); + } + return (zn); +} + +zap_name_t * +zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints) +{ + zap_name_t *zn = kmem_cache_alloc(zap_name_cache, KM_SLEEP); + + ASSERT0(zap->zap_normflags); + zn->zn_zap = zap; + zn->zn_key_intlen = sizeof (*key); + zn->zn_key_orig = zn->zn_key_norm = key; + zn->zn_key_orig_numints = zn->zn_key_norm_numints = numints; + zn->zn_matchtype = 0; + zn->zn_normbuf_len = ZAP_MAXNAMELEN; + + zn->zn_hash = zap_hash(zn); + return (zn); +} + +void +zap_name_free(zap_name_t *zn) +{ + if (zn->zn_normbuf_len == ZAP_MAXNAMELEN) { + kmem_cache_free(zap_name_cache, zn); + } else { + ASSERT3U(zn->zn_normbuf_len, ==, ZAP_MAXNAMELEN_NEW); + kmem_cache_free(zap_name_long_cache, zn); + } +} + +int +zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt) +{ + zap_t *zap = zn->zn_zap; + size_t key_len = strlen(key) + 1; + + /* Make sure zn is allocated for longname if key is long */ + IMPLY(key_len > ZAP_MAXNAMELEN, + zn->zn_normbuf_len == ZAP_MAXNAMELEN_NEW); + + zn->zn_key_intlen = sizeof (*key); + zn->zn_key_orig = key; + zn->zn_key_orig_numints = key_len; + zn->zn_matchtype = mt; + zn->zn_normflags = zap->zap_normflags; + + /* + * If we're dealing with a case sensitive lookup on a mixed or + * insensitive fs, remove U8_TEXTPREP_TOUPPER or the lookup + * will fold case to all caps overriding the lookup request. + */ + if (mt & MT_MATCH_CASE) + zn->zn_normflags &= ~U8_TEXTPREP_TOUPPER; + + if (zap->zap_normflags) { + /* + * We *must* use zap_normflags because this normalization is + * what the hash is computed from. + */ + if (zap_normalize(zap, key, zn->zn_normbuf, + zap->zap_normflags, zn->zn_normbuf_len) != 0) + return (SET_ERROR(ENOTSUP)); + zn->zn_key_norm = zn->zn_normbuf; + zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1; + } else { + if (mt != 0) + return (SET_ERROR(ENOTSUP)); + zn->zn_key_norm = zn->zn_key_orig; + zn->zn_key_norm_numints = zn->zn_key_orig_numints; + } + + zn->zn_hash = zap_hash(zn); + + if (zap->zap_normflags != zn->zn_normflags) { + /* + * We *must* use zn_normflags because this normalization is + * what the matching is based on. (Not the hash!) + */ + if (zap_normalize(zap, key, zn->zn_normbuf, + zn->zn_normflags, zn->zn_normbuf_len) != 0) + return (SET_ERROR(ENOTSUP)); + zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1; + } + + return (0); +} + +boolean_t +zap_match(zap_name_t *zn, const char *matchname) +{ + boolean_t res = B_FALSE; + ASSERT(!(zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY)); + + if (zn->zn_matchtype & MT_NORMALIZE) { + size_t namelen = zn->zn_normbuf_len; + char normbuf[ZAP_MAXNAMELEN]; + char *norm = normbuf; + + /* + * Cannot allocate this on-stack as it exceed the stack-limit of + * 1024. + */ + if (namelen > ZAP_MAXNAMELEN) + norm = kmem_alloc(namelen, KM_SLEEP); + + if (zap_normalize(zn->zn_zap, matchname, norm, + zn->zn_normflags, namelen) != 0) { + res = B_FALSE; + } else { + res = (strcmp(zn->zn_key_norm, norm) == 0); + } + if (norm != normbuf) + kmem_free(norm, namelen); + } else { + res = (strcmp(zn->zn_key_orig, matchname) == 0); + } + return (res); +} + +uint64_t +zap_hash(zap_name_t *zn) +{ + zap_t *zap = zn->zn_zap; + uint64_t h = 0; + + if (zap_getflags(zap) & ZAP_FLAG_PRE_HASHED_KEY) { + ASSERT(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY); + h = *(uint64_t *)zn->zn_key_orig; + } else { + h = zap->zap_salt; + ASSERT(h != 0); + ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY); + + if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) { + const uint64_t *wp = zn->zn_key_norm; + + ASSERT(zn->zn_key_intlen == 8); + for (int i = 0; i < zn->zn_key_norm_numints; + wp++, i++) { + uint64_t word = *wp; + + for (int j = 0; j < 8; j++) { + h = (h >> 8) ^ + zfs_crc64_table[(h ^ word) & 0xFF]; + word >>= NBBY; + } + } + } else { + const uint8_t *cp = zn->zn_key_norm; + + /* + * We previously stored the terminating null on + * disk, but didn't hash it, so we need to + * continue to not hash it. (The + * zn_key_*_numints includes the terminating + * null for non-binary keys.) + */ + int len = zn->zn_key_norm_numints - 1; + + ASSERT(zn->zn_key_intlen == 1); + for (int i = 0; i < len; cp++, i++) { + h = (h >> 8) ^ + zfs_crc64_table[(h ^ *cp) & 0xFF]; + } + } + } + /* + * Don't use all 64 bits, since we need some in the cookie for + * the collision differentiator. We MUST use the high bits, + * since those are the ones that we first pay attention to when + * choosing the bucket. + */ + h &= ~((1ULL << (64 - zap_hashbits(zap))) - 1); + + return (h); +} + /* * This routine "consumes" the caller's hold on the dbuf, which must * have the specified tag. @@ -190,146 +440,19 @@ zap_unlockdir(zap_t *zap, const void *tag) dmu_buf_rele(zap->zap_dbuf, tag); } -static kmem_cache_t *zap_name_cache; -static kmem_cache_t *zap_attr_cache; -static kmem_cache_t *zap_name_long_cache; -static kmem_cache_t *zap_attr_long_cache; - void -zap_init(void) +zap_evict_sync(void *dbu) { - zap_name_cache = kmem_cache_create("zap_name", - sizeof (zap_name_t) + ZAP_MAXNAMELEN, 0, NULL, NULL, - NULL, NULL, NULL, 0); + zap_t *zap = dbu; - zap_attr_cache = kmem_cache_create("zap_attr_cache", - sizeof (zap_attribute_t) + ZAP_MAXNAMELEN, 0, NULL, - NULL, NULL, NULL, NULL, 0); + rw_destroy(&zap->zap_rwlock); - zap_name_long_cache = kmem_cache_create("zap_name_long", - sizeof (zap_name_t) + ZAP_MAXNAMELEN_NEW, 0, NULL, NULL, - NULL, NULL, NULL, 0); + if (zap->zap_ismicro) + mze_destroy(zap); + else + mutex_destroy(&zap->zap_f.zap_num_entries_mtx); - zap_attr_long_cache = kmem_cache_create("zap_attr_long_cache", - sizeof (zap_attribute_t) + ZAP_MAXNAMELEN_NEW, 0, NULL, - NULL, NULL, NULL, NULL, 0); -} - -void -zap_fini(void) -{ - kmem_cache_destroy(zap_name_cache); - kmem_cache_destroy(zap_attr_cache); - kmem_cache_destroy(zap_name_long_cache); - kmem_cache_destroy(zap_attr_long_cache); -} - -zap_name_t * -zap_name_alloc(zap_t *zap, boolean_t longname) -{ - kmem_cache_t *cache = longname ? zap_name_long_cache : zap_name_cache; - zap_name_t *zn = kmem_cache_alloc(cache, KM_SLEEP); - - zn->zn_zap = zap; - zn->zn_normbuf_len = longname ? ZAP_MAXNAMELEN_NEW : ZAP_MAXNAMELEN; - return (zn); -} - -void -zap_name_free(zap_name_t *zn) -{ - if (zn->zn_normbuf_len == ZAP_MAXNAMELEN) { - kmem_cache_free(zap_name_cache, zn); - } else { - ASSERT3U(zn->zn_normbuf_len, ==, ZAP_MAXNAMELEN_NEW); - kmem_cache_free(zap_name_long_cache, zn); - } -} - -int -zap_name_init_str(zap_name_t *zn, const char *key, matchtype_t mt) -{ - zap_t *zap = zn->zn_zap; - size_t key_len = strlen(key) + 1; - - /* Make sure zn is allocated for longname if key is long */ - IMPLY(key_len > ZAP_MAXNAMELEN, - zn->zn_normbuf_len == ZAP_MAXNAMELEN_NEW); - - zn->zn_key_intlen = sizeof (*key); - zn->zn_key_orig = key; - zn->zn_key_orig_numints = key_len; - zn->zn_matchtype = mt; - zn->zn_normflags = zap->zap_normflags; - - /* - * If we're dealing with a case sensitive lookup on a mixed or - * insensitive fs, remove U8_TEXTPREP_TOUPPER or the lookup - * will fold case to all caps overriding the lookup request. - */ - if (mt & MT_MATCH_CASE) - zn->zn_normflags &= ~U8_TEXTPREP_TOUPPER; - - if (zap->zap_normflags) { - /* - * We *must* use zap_normflags because this normalization is - * what the hash is computed from. - */ - if (zap_normalize(zap, key, zn->zn_normbuf, - zap->zap_normflags, zn->zn_normbuf_len) != 0) - return (SET_ERROR(ENOTSUP)); - zn->zn_key_norm = zn->zn_normbuf; - zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1; - } else { - if (mt != 0) - return (SET_ERROR(ENOTSUP)); - zn->zn_key_norm = zn->zn_key_orig; - zn->zn_key_norm_numints = zn->zn_key_orig_numints; - } - - zn->zn_hash = zap_hash(zn); - - if (zap->zap_normflags != zn->zn_normflags) { - /* - * We *must* use zn_normflags because this normalization is - * what the matching is based on. (Not the hash!) - */ - if (zap_normalize(zap, key, zn->zn_normbuf, - zn->zn_normflags, zn->zn_normbuf_len) != 0) - return (SET_ERROR(ENOTSUP)); - zn->zn_key_norm_numints = strlen(zn->zn_key_norm) + 1; - } - - return (0); -} - -zap_name_t * -zap_name_alloc_str(zap_t *zap, const char *key, matchtype_t mt) -{ - size_t key_len = strlen(key) + 1; - zap_name_t *zn = zap_name_alloc(zap, (key_len > ZAP_MAXNAMELEN)); - if (zap_name_init_str(zn, key, mt) != 0) { - zap_name_free(zn); - return (NULL); - } - return (zn); -} - -zap_name_t * -zap_name_alloc_uint64(zap_t *zap, const uint64_t *key, int numints) -{ - zap_name_t *zn = kmem_cache_alloc(zap_name_cache, KM_SLEEP); - - ASSERT0(zap->zap_normflags); - zn->zn_zap = zap; - zn->zn_key_intlen = sizeof (*key); - zn->zn_key_orig = zn->zn_key_norm = key; - zn->zn_key_orig_numints = zn->zn_key_norm_numints = numints; - zn->zn_matchtype = 0; - zn->zn_normbuf_len = ZAP_MAXNAMELEN; - - zn->zn_hash = zap_hash(zn); - return (zn); + kmem_free(zap, sizeof (zap_t)); } uint64_t @@ -358,112 +481,7 @@ zap_maxcd(zap_t *zap) return (-1U); } -uint64_t -zap_hash(zap_name_t *zn) -{ - zap_t *zap = zn->zn_zap; - uint64_t h = 0; - - if (zap_getflags(zap) & ZAP_FLAG_PRE_HASHED_KEY) { - ASSERT(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY); - h = *(uint64_t *)zn->zn_key_orig; - } else { - h = zap->zap_salt; - ASSERT(h != 0); - ASSERT(zfs_crc64_table[128] == ZFS_CRC64_POLY); - - if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) { - const uint64_t *wp = zn->zn_key_norm; - - ASSERT(zn->zn_key_intlen == 8); - for (int i = 0; i < zn->zn_key_norm_numints; - wp++, i++) { - uint64_t word = *wp; - - for (int j = 0; j < 8; j++) { - h = (h >> 8) ^ - zfs_crc64_table[(h ^ word) & 0xFF]; - word >>= NBBY; - } - } - } else { - const uint8_t *cp = zn->zn_key_norm; - - /* - * We previously stored the terminating null on - * disk, but didn't hash it, so we need to - * continue to not hash it. (The - * zn_key_*_numints includes the terminating - * null for non-binary keys.) - */ - int len = zn->zn_key_norm_numints - 1; - - ASSERT(zn->zn_key_intlen == 1); - for (int i = 0; i < len; cp++, i++) { - h = (h >> 8) ^ - zfs_crc64_table[(h ^ *cp) & 0xFF]; - } - } - } - /* - * Don't use all 64 bits, since we need some in the cookie for - * the collision differentiator. We MUST use the high bits, - * since those are the ones that we first pay attention to when - * choosing the bucket. - */ - h &= ~((1ULL << (64 - zap_hashbits(zap))) - 1); - - return (h); -} - -int -zap_normalize(zap_t *zap, const char *name, char *namenorm, int normflags, - size_t outlen) -{ - ASSERT(!(zap_getflags(zap) & ZAP_FLAG_UINT64_KEY)); - - size_t inlen = strlen(name) + 1; - - int err = 0; - (void) u8_textprep_str((char *)name, &inlen, namenorm, &outlen, - normflags | U8_TEXTPREP_IGNORE_NULL | U8_TEXTPREP_IGNORE_INVALID, - U8_UNICODE_LATEST, &err); - - return (err); -} - -boolean_t -zap_match(zap_name_t *zn, const char *matchname) -{ - boolean_t res = B_FALSE; - ASSERT(!(zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY)); - - if (zn->zn_matchtype & MT_NORMALIZE) { - size_t namelen = zn->zn_normbuf_len; - char normbuf[ZAP_MAXNAMELEN]; - char *norm = normbuf; - - /* - * Cannot allocate this on-stack as it exceed the stack-limit of - * 1024. - */ - if (namelen > ZAP_MAXNAMELEN) - norm = kmem_alloc(namelen, KM_SLEEP); - - if (zap_normalize(zn->zn_zap, matchname, norm, - zn->zn_normflags, namelen) != 0) { - res = B_FALSE; - } else { - res = (strcmp(zn->zn_key_norm, norm) == 0); - } - if (norm != normbuf) - kmem_free(norm, namelen); - } else { - res = (strcmp(zn->zn_key_orig, matchname) == 0); - } - return (res); -} - +/* DNU byteswap callback for DMU_BSWAP_ZAP, see dmu_ot_byteswap. */ void zap_byteswap(void *buf, size_t size) { @@ -477,21 +495,10 @@ zap_byteswap(void *buf, size_t size) } } -void -zap_evict_sync(void *dbu) -{ - zap_t *zap = dbu; - - rw_destroy(&zap->zap_rwlock); - - if (zap->zap_ismicro) - mze_destroy(zap); - else - mutex_destroy(&zap->zap_f.zap_num_entries_mtx); - - kmem_free(zap, sizeof (zap_t)); -} - +/* + * Cursor attribute allocator/free. Part of the public interface in zap.h, + * in this file to get access to the kmem caches. + */ static zap_attribute_t * zap_attribute_alloc_impl(boolean_t longname) {