xref: /illumos-gate/usr/src/uts/common/fs/zfs/sys/zap_leaf.h (revision 65a89a64c60f3061bbe2381edaacc81660af9a95)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_ZAP_LEAF_H
28 #define	_SYS_ZAP_LEAF_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 struct zap;
37 
38 #define	ZAP_LEAF_MAGIC 0x2AB1EAF
39 
40 /* chunk size = 24 bytes */
41 
42 #define	ZAP_LEAF_NUMCHUNKS 5118
43 #define	ZAP_LEAF_ARRAY_BYTES 21
44 #define	ZAP_LEAF_HASH_SHIFT 12
45 #define	ZAP_LEAF_HASH_NUMENTRIES (1 << ZAP_LEAF_HASH_SHIFT)
46 #define	ZAP_LLA_DATA_BYTES ((1 << ZAP_BLOCK_SHIFT) - 16)
47 
48 typedef enum zap_entry_type {
49 	ZAP_LEAF_FREE = 253,
50 	ZAP_LEAF_ENTRY = 252,
51 	ZAP_LEAF_ARRAY = 251,
52 	ZAP_LEAF_TYPE_MAX = 250
53 } zap_entry_type_t;
54 
55 /*
56  * TAKE NOTE:
57  * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified.
58  */
59 typedef struct zap_leaf_phys {
60 	struct zap_leaf_header {
61 		uint64_t lhr_block_type;	/* ZBT_LEAF */
62 		uint64_t lhr_next;		/* next block in leaf chain */
63 		uint64_t lhr_prefix;
64 		uint32_t lhr_magic;		/* ZAP_LEAF_MAGIC */
65 		uint16_t lhr_nfree;		/* number free chunks */
66 		uint16_t lhr_nentries;		/* number of entries */
67 		uint16_t lhr_prefix_len;
68 
69 #define	lh_block_type 	l_phys->l_hdr.lhr_block_type
70 #define	lh_magic 	l_phys->l_hdr.lhr_magic
71 #define	lh_next 	l_phys->l_hdr.lhr_next
72 #define	lh_prefix 	l_phys->l_hdr.lhr_prefix
73 #define	lh_nfree 	l_phys->l_hdr.lhr_nfree
74 #define	lh_prefix_len 	l_phys->l_hdr.lhr_prefix_len
75 #define	lh_nentries 	l_phys->l_hdr.lhr_nentries
76 
77 /* above is accessable to zap, below is zap_leaf private */
78 
79 		uint16_t lh_freelist;		/* chunk head of free list */
80 		uint8_t lh_pad2[12];
81 	} l_hdr; /* 2 24-byte chunks */
82 
83 	uint16_t l_hash[ZAP_LEAF_HASH_NUMENTRIES];
84 	/* 170 24-byte chunks plus 16 bytes leftover space */
85 
86 	union zap_leaf_chunk {
87 		struct zap_leaf_entry {
88 			uint8_t le_type; 	/* always ZAP_LEAF_ENTRY */
89 			uint8_t le_int_size;	/* size of ints */
90 			uint16_t le_next;	/* next entry in hash chain */
91 			uint16_t le_name_chunk;	/* first chunk of the name */
92 			uint16_t le_name_length; /* bytes in name, incl null */
93 			uint16_t le_value_chunk; /* first chunk of the value */
94 			uint16_t le_value_length; /* value length in ints */
95 			uint32_t le_cd;		/* collision differentiator */
96 			uint64_t le_hash;	/* hash value of the name */
97 		} l_entry;
98 		struct zap_leaf_array {
99 			uint8_t la_type;
100 			uint8_t la_array[ZAP_LEAF_ARRAY_BYTES];
101 			uint16_t la_next;	/* next blk or CHAIN_END */
102 		} l_array;
103 		struct zap_leaf_free {
104 			uint8_t lf_type;	/* always ZAP_LEAF_FREE */
105 			uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES];
106 			uint16_t lf_next;  /* next in free list, or CHAIN_END */
107 		} l_free;
108 	} l_chunk[ZAP_LEAF_NUMCHUNKS];
109 } zap_leaf_phys_t;
110 
111 typedef struct zap_leaf {
112 	krwlock_t l_rwlock; 		/* only used on head of chain */
113 	uint64_t l_blkid;		/* 1<<ZAP_BLOCK_SHIFT byte block off */
114 	struct zap_leaf *l_next;	/* next in chain */
115 	dmu_buf_t *l_dbuf;
116 	zap_leaf_phys_t *l_phys;
117 } zap_leaf_t;
118 
119 
120 typedef struct zap_entry_handle {
121 	/* below is set by zap_leaf.c and is public to zap.c */
122 	uint64_t zeh_num_integers;
123 	uint64_t zeh_hash;
124 	uint32_t zeh_cd;
125 	uint8_t zeh_integer_size;
126 
127 	/* below is private to zap_leaf.c */
128 	uint16_t zeh_fakechunk;
129 	uint16_t *zeh_chunkp;
130 	zap_leaf_t *zeh_head_leaf;
131 	zap_leaf_t *zeh_found_leaf;
132 } zap_entry_handle_t;
133 
134 /*
135  * Return a handle to the named entry, or ENOENT if not found.  The hash
136  * value must equal zap_hash(name).
137  */
138 extern int zap_leaf_lookup(zap_leaf_t *l,
139 	const char *name, uint64_t h, zap_entry_handle_t *zeh);
140 
141 /*
142  * Return a handle to the entry with this hash+cd, or the entry with the
143  * next closest hash+cd.
144  */
145 extern int zap_leaf_lookup_closest(zap_leaf_t *l,
146     uint64_t hash, uint32_t cd, zap_entry_handle_t *zeh);
147 
148 /*
149  * Read the first num_integers in the attribute.  Integer size
150  * conversion will be done without sign extension.  Return EINVAL if
151  * integer_size is too small.  Return EOVERFLOW if there are more than
152  * num_integers in the attribute.
153  */
154 extern int zap_entry_read(const zap_entry_handle_t *zeh,
155 	uint8_t integer_size, uint64_t num_integers, void *buf);
156 
157 extern int zap_entry_read_name(const zap_entry_handle_t *zeh,
158 	uint16_t buflen, char *buf);
159 
160 /*
161  * Replace the value of an existing entry.
162  *
163  * zap_entry_update may fail if it runs out of space (ENOSPC).
164  */
165 extern int zap_entry_update(zap_entry_handle_t *zeh,
166 	uint8_t integer_size, uint64_t num_integers, const void *buf);
167 
168 /*
169  * Remove an entry.
170  */
171 extern void zap_entry_remove(zap_entry_handle_t *zeh);
172 
173 /*
174  * Create an entry. An equal entry must not exist, and this entry must
175  * belong in this leaf (according to its hash value).  Fills in the
176  * entry handle on success.  Returns 0 on success or ENOSPC on failure.
177  */
178 extern int zap_entry_create(zap_leaf_t *l,
179 	const char *name, uint64_t h, uint32_t cd,
180 	uint8_t integer_size, uint64_t num_integers, const void *buf,
181 	zap_entry_handle_t *zeh);
182 
183 /*
184  * Other stuff.
185  */
186 
187 extern void zap_leaf_init(zap_leaf_t *l);
188 extern void zap_leaf_byteswap(zap_leaf_phys_t *buf);
189 
190 extern zap_leaf_t *zap_leaf_split(struct zap *zap, zap_leaf_t *l, dmu_tx_t *tx);
191 
192 extern int zap_leaf_merge(zap_leaf_t *l, zap_leaf_t *sibling);
193 
194 extern zap_leaf_t *zap_leaf_chainmore(zap_leaf_t *l, zap_leaf_t *nl);
195 
196 extern int zap_leaf_advance(zap_leaf_t *l, zap_cursor_t *zc);
197 
198 extern void zap_stats_leaf(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs);
199 
200 #ifdef	__cplusplus
201 }
202 #endif
203 
204 #endif /* _SYS_ZAP_LEAF_H */
205