xref: /onnv-gate/usr/src/uts/common/fs/zfs/sys/zap_leaf.h (revision 12296:7cf402a7f374)
1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
51491Sahrens  * Common Development and Distribution License (the "License").
61491Sahrens  * You may not use this file except in compliance with the License.
7789Sahrens  *
8789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9789Sahrens  * or http://www.opensolaris.org/os/licensing.
10789Sahrens  * See the License for the specific language governing permissions
11789Sahrens  * and limitations under the License.
12789Sahrens  *
13789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18789Sahrens  *
19789Sahrens  * CDDL HEADER END
20789Sahrens  */
21789Sahrens /*
22*12296SLin.Ling@Sun.COM  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23789Sahrens  */
24789Sahrens 
25789Sahrens #ifndef	_SYS_ZAP_LEAF_H
26789Sahrens #define	_SYS_ZAP_LEAF_H
27789Sahrens 
28*12296SLin.Ling@Sun.COM #include <sys/zap.h>
29*12296SLin.Ling@Sun.COM 
30789Sahrens #ifdef	__cplusplus
31789Sahrens extern "C" {
32789Sahrens #endif
33789Sahrens 
34789Sahrens struct zap;
3511609SMatthew.Ahrens@Sun.COM struct zap_name;
3611609SMatthew.Ahrens@Sun.COM struct zap_stats;
37789Sahrens 
38789Sahrens #define	ZAP_LEAF_MAGIC 0x2AB1EAF
39789Sahrens 
40789Sahrens /* chunk size = 24 bytes */
411491Sahrens #define	ZAP_LEAF_CHUNKSIZE 24
42789Sahrens 
431491Sahrens /*
441491Sahrens  * The amount of space available for chunks is:
451491Sahrens  * block size (1<<l->l_bs) - hash entry size (2) * number of hash
461491Sahrens  * entries - header space (2*chunksize)
471491Sahrens  */
481491Sahrens #define	ZAP_LEAF_NUMCHUNKS(l) \
491491Sahrens 	(((1<<(l)->l_bs) - 2*ZAP_LEAF_HASH_NUMENTRIES(l)) / \
501491Sahrens 	ZAP_LEAF_CHUNKSIZE - 2)
511491Sahrens 
521491Sahrens /*
531491Sahrens  * The amount of space within the chunk available for the array is:
541491Sahrens  * chunk size - space for type (1) - space for next pointer (2)
551491Sahrens  */
561491Sahrens #define	ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3)
57789Sahrens 
581578Sahrens #define	ZAP_LEAF_ARRAY_NCHUNKS(bytes) \
591578Sahrens 	(((bytes)+ZAP_LEAF_ARRAY_BYTES-1)/ZAP_LEAF_ARRAY_BYTES)
601578Sahrens 
611578Sahrens /*
621578Sahrens  * Low water mark:  when there are only this many chunks free, start
631578Sahrens  * growing the ptrtbl.  Ideally, this should be larger than a
641578Sahrens  * "reasonably-sized" entry.  20 chunks is more than enough for the
651578Sahrens  * largest directory entry (MAXNAMELEN (256) byte name, 8-byte value),
661578Sahrens  * while still being only around 3% for 16k blocks.
671578Sahrens  */
681578Sahrens #define	ZAP_LEAF_LOW_WATER (20)
691578Sahrens 
701491Sahrens /*
711491Sahrens  * The leaf hash table has block size / 2^5 (32) number of entries,
721491Sahrens  * which should be more than enough for the maximum number of entries,
731491Sahrens  * which is less than block size / CHUNKSIZE (24) / minimum number of
741491Sahrens  * chunks per entry (3).
751491Sahrens  */
761491Sahrens #define	ZAP_LEAF_HASH_SHIFT(l) ((l)->l_bs - 5)
771491Sahrens #define	ZAP_LEAF_HASH_NUMENTRIES(l) (1 << ZAP_LEAF_HASH_SHIFT(l))
781491Sahrens 
791491Sahrens /*
801491Sahrens  * The chunks start immediately after the hash table.  The end of the
811491Sahrens  * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a
821491Sahrens  * chunk_t.
831491Sahrens  */
841491Sahrens #define	ZAP_LEAF_CHUNK(l, idx) \
851491Sahrens 	((zap_leaf_chunk_t *) \
861491Sahrens 	((l)->l_phys->l_hash + ZAP_LEAF_HASH_NUMENTRIES(l)))[idx]
871491Sahrens #define	ZAP_LEAF_ENTRY(l, idx) (&ZAP_LEAF_CHUNK(l, idx).l_entry)
881491Sahrens 
891491Sahrens typedef enum zap_chunk_type {
901491Sahrens 	ZAP_CHUNK_FREE = 253,
911491Sahrens 	ZAP_CHUNK_ENTRY = 252,
921491Sahrens 	ZAP_CHUNK_ARRAY = 251,
931491Sahrens 	ZAP_CHUNK_TYPE_MAX = 250
941491Sahrens } zap_chunk_type_t;
95789Sahrens 
965331Samw #define	ZLF_ENTRIES_CDSORTED (1<<0)
975331Samw 
98789Sahrens /*
99789Sahrens  * TAKE NOTE:
100789Sahrens  * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified.
101789Sahrens  */
102789Sahrens typedef struct zap_leaf_phys {
103789Sahrens 	struct zap_leaf_header {
1041578Sahrens 		uint64_t lh_block_type;		/* ZBT_LEAF */
1051578Sahrens 		uint64_t lh_pad1;
1061578Sahrens 		uint64_t lh_prefix;		/* hash prefix of this leaf */
1071578Sahrens 		uint32_t lh_magic;		/* ZAP_LEAF_MAGIC */
1081578Sahrens 		uint16_t lh_nfree;		/* number free chunks */
1091578Sahrens 		uint16_t lh_nentries;		/* number of entries */
1101578Sahrens 		uint16_t lh_prefix_len;		/* num bits used to id this */
111789Sahrens 
112789Sahrens /* above is accessable to zap, below is zap_leaf private */
113789Sahrens 
114789Sahrens 		uint16_t lh_freelist;		/* chunk head of free list */
1155331Samw 		uint8_t lh_flags;		/* ZLF_* flags */
1165331Samw 		uint8_t lh_pad2[11];
117789Sahrens 	} l_hdr; /* 2 24-byte chunks */
118789Sahrens 
1191491Sahrens 	/*
1201491Sahrens 	 * The header is followed by a hash table with
1211491Sahrens 	 * ZAP_LEAF_HASH_NUMENTRIES(zap) entries.  The hash table is
1221491Sahrens 	 * followed by an array of ZAP_LEAF_NUMCHUNKS(zap)
1231491Sahrens 	 * zap_leaf_chunk structures.  These structures are accessed
1241491Sahrens 	 * with the ZAP_LEAF_CHUNK() macro.
1251491Sahrens 	 */
1261491Sahrens 
1271491Sahrens 	uint16_t l_hash[1];
1281491Sahrens } zap_leaf_phys_t;
129789Sahrens 
1301491Sahrens typedef union zap_leaf_chunk {
1311491Sahrens 	struct zap_leaf_entry {
1321491Sahrens 		uint8_t le_type; 		/* always ZAP_CHUNK_ENTRY */
13311165SMatthew.Ahrens@Sun.COM 		uint8_t le_value_intlen;	/* size of value's ints */
1341491Sahrens 		uint16_t le_next;		/* next entry in hash chain */
1351491Sahrens 		uint16_t le_name_chunk;		/* first chunk of the name */
13611165SMatthew.Ahrens@Sun.COM 		uint16_t le_name_numints;	/* ints in name (incl null) */
1371491Sahrens 		uint16_t le_value_chunk;	/* first chunk of the value */
13811165SMatthew.Ahrens@Sun.COM 		uint16_t le_value_numints;	/* value length in ints */
1391491Sahrens 		uint32_t le_cd;			/* collision differentiator */
1401491Sahrens 		uint64_t le_hash;		/* hash value of the name */
1411491Sahrens 	} l_entry;
1421491Sahrens 	struct zap_leaf_array {
1431491Sahrens 		uint8_t la_type;		/* always ZAP_CHUNK_ARRAY */
1441491Sahrens 		uint8_t la_array[ZAP_LEAF_ARRAY_BYTES];
1451491Sahrens 		uint16_t la_next;		/* next blk or CHAIN_END */
1461491Sahrens 	} l_array;
1471491Sahrens 	struct zap_leaf_free {
1481491Sahrens 		uint8_t lf_type;		/* always ZAP_CHUNK_FREE */
1491491Sahrens 		uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES];
1501491Sahrens 		uint16_t lf_next;	/* next in free list, or CHAIN_END */
1511491Sahrens 	} l_free;
1521491Sahrens } zap_leaf_chunk_t;
153789Sahrens 
154789Sahrens typedef struct zap_leaf {
1557046Sahrens 	krwlock_t l_rwlock;
156789Sahrens 	uint64_t l_blkid;		/* 1<<ZAP_BLOCK_SHIFT byte block off */
1571491Sahrens 	int l_bs;			/* block size shift */
158789Sahrens 	dmu_buf_t *l_dbuf;
159789Sahrens 	zap_leaf_phys_t *l_phys;
160789Sahrens } zap_leaf_t;
161789Sahrens 
162789Sahrens 
163789Sahrens typedef struct zap_entry_handle {
164789Sahrens 	/* below is set by zap_leaf.c and is public to zap.c */
165789Sahrens 	uint64_t zeh_num_integers;
166789Sahrens 	uint64_t zeh_hash;
167789Sahrens 	uint32_t zeh_cd;
168789Sahrens 	uint8_t zeh_integer_size;
169789Sahrens 
170789Sahrens 	/* below is private to zap_leaf.c */
171789Sahrens 	uint16_t zeh_fakechunk;
172789Sahrens 	uint16_t *zeh_chunkp;
1731578Sahrens 	zap_leaf_t *zeh_leaf;
174789Sahrens } zap_entry_handle_t;
175789Sahrens 
176789Sahrens /*
177789Sahrens  * Return a handle to the named entry, or ENOENT if not found.  The hash
178789Sahrens  * value must equal zap_hash(name).
179789Sahrens  */
180789Sahrens extern int zap_leaf_lookup(zap_leaf_t *l,
18111609SMatthew.Ahrens@Sun.COM     struct zap_name *zn, zap_entry_handle_t *zeh);
182789Sahrens 
183789Sahrens /*
184789Sahrens  * Return a handle to the entry with this hash+cd, or the entry with the
185789Sahrens  * next closest hash+cd.
186789Sahrens  */
187789Sahrens extern int zap_leaf_lookup_closest(zap_leaf_t *l,
188789Sahrens     uint64_t hash, uint32_t cd, zap_entry_handle_t *zeh);
189789Sahrens 
190789Sahrens /*
191789Sahrens  * Read the first num_integers in the attribute.  Integer size
192789Sahrens  * conversion will be done without sign extension.  Return EINVAL if
193789Sahrens  * integer_size is too small.  Return EOVERFLOW if there are more than
194789Sahrens  * num_integers in the attribute.
195789Sahrens  */
196789Sahrens extern int zap_entry_read(const zap_entry_handle_t *zeh,
19710922SJeff.Bonwick@Sun.COM     uint8_t integer_size, uint64_t num_integers, void *buf);
198789Sahrens 
19911609SMatthew.Ahrens@Sun.COM extern int zap_entry_read_name(struct zap *zap, const zap_entry_handle_t *zeh,
20010922SJeff.Bonwick@Sun.COM     uint16_t buflen, char *buf);
201789Sahrens 
202789Sahrens /*
203789Sahrens  * Replace the value of an existing entry.
204789Sahrens  *
205789Sahrens  * zap_entry_update may fail if it runs out of space (ENOSPC).
206789Sahrens  */
207789Sahrens extern int zap_entry_update(zap_entry_handle_t *zeh,
20810922SJeff.Bonwick@Sun.COM     uint8_t integer_size, uint64_t num_integers, const void *buf);
209789Sahrens 
210789Sahrens /*
211789Sahrens  * Remove an entry.
212789Sahrens  */
213789Sahrens extern void zap_entry_remove(zap_entry_handle_t *zeh);
214789Sahrens 
215789Sahrens /*
216789Sahrens  * Create an entry. An equal entry must not exist, and this entry must
217789Sahrens  * belong in this leaf (according to its hash value).  Fills in the
218789Sahrens  * entry handle on success.  Returns 0 on success or ENOSPC on failure.
219789Sahrens  */
22011609SMatthew.Ahrens@Sun.COM extern int zap_entry_create(zap_leaf_t *l, struct zap_name *zn, uint32_t cd,
22110922SJeff.Bonwick@Sun.COM     uint8_t integer_size, uint64_t num_integers, const void *buf,
22210922SJeff.Bonwick@Sun.COM     zap_entry_handle_t *zeh);
223789Sahrens 
224789Sahrens /*
2255331Samw  * Return true if there are additional entries with the same normalized
2265331Samw  * form.
2275331Samw  */
2285331Samw extern boolean_t zap_entry_normalization_conflict(zap_entry_handle_t *zeh,
22911609SMatthew.Ahrens@Sun.COM     struct zap_name *zn, const char *name, struct zap *zap);
2305331Samw 
2315331Samw /*
232789Sahrens  * Other stuff.
233789Sahrens  */
234789Sahrens 
2355498Stimh extern void zap_leaf_init(zap_leaf_t *l, boolean_t sort);
2361491Sahrens extern void zap_leaf_byteswap(zap_leaf_phys_t *buf, int len);
2375498Stimh extern void zap_leaf_split(zap_leaf_t *l, zap_leaf_t *nl, boolean_t sort);
23811609SMatthew.Ahrens@Sun.COM extern void zap_leaf_stats(struct zap *zap, zap_leaf_t *l,
23911609SMatthew.Ahrens@Sun.COM     struct zap_stats *zs);
240789Sahrens 
241789Sahrens #ifdef	__cplusplus
242789Sahrens }
243789Sahrens #endif
244789Sahrens 
245789Sahrens #endif /* _SYS_ZAP_LEAF_H */
246