author | Joshua M. Clulow <jmc@joyent.com> |
Mon, 04 Mar 2013 23:52:56 +0000 | |
changeset 14188 | afe390b9f1e0 |
parent 13980 | d7059eb1884c |
permissions | -rw-r--r-- |
789 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
5 |
* Common Development and Distribution License (the "License"). |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
6 |
* You may not use this file except in compliance with the License. |
789 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
21 |
/* |
|
12296
7cf402a7f374
6675946 'zpool status' should show the progress of resilvering for individual disk.
Lin Ling <Lin.Ling@Sun.COM>
parents:
11165
diff
changeset
|
22 |
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
23 |
* Copyright (c) 2013 by Delphix. All rights reserved. |
789 | 24 |
*/ |
25 |
||
26 |
/* |
|
27 |
* The 512-byte leaf is broken into 32 16-byte chunks. |
|
28 |
* chunk number n means l_chunk[n], even though the header precedes it. |
|
29 |
* the names are stored null-terminated. |
|
30 |
*/ |
|
31 |
||
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
32 |
#include <sys/zio.h> |
9643
ffd8e7765f02
6736004 zvols need an additional property for comstar support
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
5498
diff
changeset
|
33 |
#include <sys/spa.h> |
ffd8e7765f02
6736004 zvols need an additional property for comstar support
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
5498
diff
changeset
|
34 |
#include <sys/dmu.h> |
789 | 35 |
#include <sys/zfs_context.h> |
9643
ffd8e7765f02
6736004 zvols need an additional property for comstar support
Eric Taylor <Eric.Taylor@Sun.COM>
parents:
5498
diff
changeset
|
36 |
#include <sys/fs/zfs.h> |
789 | 37 |
#include <sys/zap.h> |
38 |
#include <sys/zap_impl.h> |
|
39 |
#include <sys/zap_leaf.h> |
|
12296
7cf402a7f374
6675946 'zpool status' should show the progress of resilvering for individual disk.
Lin Ling <Lin.Ling@Sun.COM>
parents:
11165
diff
changeset
|
40 |
#include <sys/arc.h> |
789 | 41 |
|
5331 | 42 |
static uint16_t *zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry); |
43 |
||
789 | 44 |
#define CHAIN_END 0xffff /* end of the chunk chain */ |
45 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
46 |
/* half the (current) minimum block size */ |
789 | 47 |
#define MAX_ARRAY_BYTES (8<<10) |
48 |
||
49 |
#define LEAF_HASH(l, h) \ |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
50 |
((ZAP_LEAF_HASH_NUMENTRIES(l)-1) & \ |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
51 |
((h) >> (64 - ZAP_LEAF_HASH_SHIFT(l)-(l)->l_phys->l_hdr.lh_prefix_len))) |
789 | 52 |
|
53 |
#define LEAF_HASH_ENTPTR(l, h) (&(l)->l_phys->l_hash[LEAF_HASH(l, h)]) |
|
54 |
||
55 |
||
56 |
static void |
|
57 |
zap_memset(void *a, int c, size_t n) |
|
58 |
{ |
|
59 |
char *cp = a; |
|
60 |
char *cpend = cp + n; |
|
61 |
||
62 |
while (cp < cpend) |
|
63 |
*cp++ = c; |
|
64 |
} |
|
65 |
||
66 |
static void |
|
67 |
stv(int len, void *addr, uint64_t value) |
|
68 |
{ |
|
69 |
switch (len) { |
|
70 |
case 1: |
|
71 |
*(uint8_t *)addr = value; |
|
72 |
return; |
|
73 |
case 2: |
|
74 |
*(uint16_t *)addr = value; |
|
75 |
return; |
|
76 |
case 4: |
|
77 |
*(uint32_t *)addr = value; |
|
78 |
return; |
|
79 |
case 8: |
|
80 |
*(uint64_t *)addr = value; |
|
81 |
return; |
|
82 |
} |
|
83 |
ASSERT(!"bad int len"); |
|
84 |
} |
|
85 |
||
86 |
static uint64_t |
|
87 |
ldv(int len, const void *addr) |
|
88 |
{ |
|
89 |
switch (len) { |
|
90 |
case 1: |
|
91 |
return (*(uint8_t *)addr); |
|
92 |
case 2: |
|
93 |
return (*(uint16_t *)addr); |
|
94 |
case 4: |
|
95 |
return (*(uint32_t *)addr); |
|
96 |
case 8: |
|
97 |
return (*(uint64_t *)addr); |
|
98 |
} |
|
99 |
ASSERT(!"bad int len"); |
|
2856 | 100 |
return (0xFEEDFACEDEADBEEFULL); |
789 | 101 |
} |
102 |
||
103 |
void |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
104 |
zap_leaf_byteswap(zap_leaf_phys_t *buf, int size) |
789 | 105 |
{ |
106 |
int i; |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
107 |
zap_leaf_t l; |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
108 |
l.l_bs = highbit(size)-1; |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
109 |
l.l_phys = buf; |
789 | 110 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
111 |
buf->l_hdr.lh_block_type = BSWAP_64(buf->l_hdr.lh_block_type); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
112 |
buf->l_hdr.lh_prefix = BSWAP_64(buf->l_hdr.lh_prefix); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
113 |
buf->l_hdr.lh_magic = BSWAP_32(buf->l_hdr.lh_magic); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
114 |
buf->l_hdr.lh_nfree = BSWAP_16(buf->l_hdr.lh_nfree); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
115 |
buf->l_hdr.lh_nentries = BSWAP_16(buf->l_hdr.lh_nentries); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
116 |
buf->l_hdr.lh_prefix_len = BSWAP_16(buf->l_hdr.lh_prefix_len); |
789 | 117 |
buf->l_hdr.lh_freelist = BSWAP_16(buf->l_hdr.lh_freelist); |
118 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
119 |
for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(&l); i++) |
789 | 120 |
buf->l_hash[i] = BSWAP_16(buf->l_hash[i]); |
121 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
122 |
for (i = 0; i < ZAP_LEAF_NUMCHUNKS(&l); i++) { |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
123 |
zap_leaf_chunk_t *lc = &ZAP_LEAF_CHUNK(&l, i); |
789 | 124 |
struct zap_leaf_entry *le; |
125 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
126 |
switch (lc->l_free.lf_type) { |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
127 |
case ZAP_CHUNK_ENTRY: |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
128 |
le = &lc->l_entry; |
789 | 129 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
130 |
le->le_type = BSWAP_8(le->le_type); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
131 |
le->le_value_intlen = BSWAP_8(le->le_value_intlen); |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
132 |
le->le_next = BSWAP_16(le->le_next); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
133 |
le->le_name_chunk = BSWAP_16(le->le_name_chunk); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
134 |
le->le_name_numints = BSWAP_16(le->le_name_numints); |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
135 |
le->le_value_chunk = BSWAP_16(le->le_value_chunk); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
136 |
le->le_value_numints = BSWAP_16(le->le_value_numints); |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
137 |
le->le_cd = BSWAP_32(le->le_cd); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
138 |
le->le_hash = BSWAP_64(le->le_hash); |
789 | 139 |
break; |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
140 |
case ZAP_CHUNK_FREE: |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
141 |
lc->l_free.lf_type = BSWAP_8(lc->l_free.lf_type); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
142 |
lc->l_free.lf_next = BSWAP_16(lc->l_free.lf_next); |
789 | 143 |
break; |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
144 |
case ZAP_CHUNK_ARRAY: |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
145 |
lc->l_array.la_type = BSWAP_8(lc->l_array.la_type); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
146 |
lc->l_array.la_next = BSWAP_16(lc->l_array.la_next); |
789 | 147 |
/* la_array doesn't need swapping */ |
148 |
break; |
|
149 |
default: |
|
150 |
ASSERT(!"bad leaf type"); |
|
151 |
} |
|
152 |
} |
|
153 |
} |
|
154 |
||
155 |
void |
|
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5331
diff
changeset
|
156 |
zap_leaf_init(zap_leaf_t *l, boolean_t sort) |
789 | 157 |
{ |
158 |
int i; |
|
159 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
160 |
l->l_bs = highbit(l->l_dbuf->db_size)-1; |
789 | 161 |
zap_memset(&l->l_phys->l_hdr, 0, sizeof (struct zap_leaf_header)); |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
162 |
zap_memset(l->l_phys->l_hash, CHAIN_END, 2*ZAP_LEAF_HASH_NUMENTRIES(l)); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
163 |
for (i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) { |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
164 |
ZAP_LEAF_CHUNK(l, i).l_free.lf_type = ZAP_CHUNK_FREE; |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
165 |
ZAP_LEAF_CHUNK(l, i).l_free.lf_next = i+1; |
789 | 166 |
} |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
167 |
ZAP_LEAF_CHUNK(l, ZAP_LEAF_NUMCHUNKS(l)-1).l_free.lf_next = CHAIN_END; |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
168 |
l->l_phys->l_hdr.lh_block_type = ZBT_LEAF; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
169 |
l->l_phys->l_hdr.lh_magic = ZAP_LEAF_MAGIC; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
170 |
l->l_phys->l_hdr.lh_nfree = ZAP_LEAF_NUMCHUNKS(l); |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5331
diff
changeset
|
171 |
if (sort) |
5331 | 172 |
l->l_phys->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED; |
789 | 173 |
} |
174 |
||
175 |
/* |
|
176 |
* Routines which manipulate leaf chunks (l_chunk[]). |
|
177 |
*/ |
|
178 |
||
179 |
static uint16_t |
|
180 |
zap_leaf_chunk_alloc(zap_leaf_t *l) |
|
181 |
{ |
|
182 |
int chunk; |
|
183 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
184 |
ASSERT(l->l_phys->l_hdr.lh_nfree > 0); |
789 | 185 |
|
186 |
chunk = l->l_phys->l_hdr.lh_freelist; |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
187 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
188 |
ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_free.lf_type, ==, ZAP_CHUNK_FREE); |
789 | 189 |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
190 |
l->l_phys->l_hdr.lh_freelist = ZAP_LEAF_CHUNK(l, chunk).l_free.lf_next; |
789 | 191 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
192 |
l->l_phys->l_hdr.lh_nfree--; |
789 | 193 |
|
194 |
return (chunk); |
|
195 |
} |
|
196 |
||
197 |
static void |
|
198 |
zap_leaf_chunk_free(zap_leaf_t *l, uint16_t chunk) |
|
199 |
{ |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
200 |
struct zap_leaf_free *zlf = &ZAP_LEAF_CHUNK(l, chunk).l_free; |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
201 |
ASSERT3U(l->l_phys->l_hdr.lh_nfree, <, ZAP_LEAF_NUMCHUNKS(l)); |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
202 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
203 |
ASSERT(zlf->lf_type != ZAP_CHUNK_FREE); |
789 | 204 |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
205 |
zlf->lf_type = ZAP_CHUNK_FREE; |
789 | 206 |
zlf->lf_next = l->l_phys->l_hdr.lh_freelist; |
207 |
bzero(zlf->lf_pad, sizeof (zlf->lf_pad)); /* help it to compress */ |
|
208 |
l->l_phys->l_hdr.lh_freelist = chunk; |
|
209 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
210 |
l->l_phys->l_hdr.lh_nfree++; |
789 | 211 |
} |
212 |
||
213 |
/* |
|
214 |
* Routines which manipulate leaf arrays (zap_leaf_array type chunks). |
|
215 |
*/ |
|
216 |
||
217 |
static uint16_t |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
218 |
zap_leaf_array_create(zap_leaf_t *l, const char *buf, |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
219 |
int integer_size, int num_integers) |
789 | 220 |
{ |
221 |
uint16_t chunk_head; |
|
222 |
uint16_t *chunkp = &chunk_head; |
|
223 |
int byten = 0; |
|
13952
7a22d0770fc8
3522 zfs module should not allow uninitialized variables
George Wilson <george.wilson@delphix.com>
parents:
12296
diff
changeset
|
224 |
uint64_t value = 0; |
789 | 225 |
int shift = (integer_size-1)*8; |
226 |
int len = num_integers; |
|
227 |
||
228 |
ASSERT3U(num_integers * integer_size, <, MAX_ARRAY_BYTES); |
|
229 |
||
230 |
while (len > 0) { |
|
231 |
uint16_t chunk = zap_leaf_chunk_alloc(l); |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
232 |
struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; |
789 | 233 |
int i; |
234 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
235 |
la->la_type = ZAP_CHUNK_ARRAY; |
789 | 236 |
for (i = 0; i < ZAP_LEAF_ARRAY_BYTES; i++) { |
237 |
if (byten == 0) |
|
238 |
value = ldv(integer_size, buf); |
|
3052
7a3625b7393b
6489548 zap_leaf_array_create() relies on architecture-specific behavior
ahrens
parents:
2856
diff
changeset
|
239 |
la->la_array[i] = value >> shift; |
789 | 240 |
value <<= 8; |
241 |
if (++byten == integer_size) { |
|
242 |
byten = 0; |
|
243 |
buf += integer_size; |
|
244 |
if (--len == 0) |
|
245 |
break; |
|
246 |
} |
|
247 |
} |
|
248 |
||
249 |
*chunkp = chunk; |
|
250 |
chunkp = &la->la_next; |
|
251 |
} |
|
252 |
*chunkp = CHAIN_END; |
|
253 |
||
254 |
return (chunk_head); |
|
255 |
} |
|
256 |
||
257 |
static void |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
258 |
zap_leaf_array_free(zap_leaf_t *l, uint16_t *chunkp) |
789 | 259 |
{ |
260 |
uint16_t chunk = *chunkp; |
|
261 |
||
262 |
*chunkp = CHAIN_END; |
|
263 |
||
264 |
while (chunk != CHAIN_END) { |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
265 |
int nextchunk = ZAP_LEAF_CHUNK(l, chunk).l_array.la_next; |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
266 |
ASSERT3U(ZAP_LEAF_CHUNK(l, chunk).l_array.la_type, ==, |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
267 |
ZAP_CHUNK_ARRAY); |
789 | 268 |
zap_leaf_chunk_free(l, chunk); |
269 |
chunk = nextchunk; |
|
270 |
} |
|
271 |
} |
|
272 |
||
273 |
/* array_len and buf_len are in integers, not bytes */ |
|
274 |
static void |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
275 |
zap_leaf_array_read(zap_leaf_t *l, uint16_t chunk, |
789 | 276 |
int array_int_len, int array_len, int buf_int_len, uint64_t buf_len, |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
277 |
void *buf) |
789 | 278 |
{ |
279 |
int len = MIN(array_len, buf_len); |
|
280 |
int byten = 0; |
|
281 |
uint64_t value = 0; |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
282 |
char *p = buf; |
789 | 283 |
|
284 |
ASSERT3U(array_int_len, <=, buf_int_len); |
|
285 |
||
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
286 |
/* Fast path for one 8-byte integer */ |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
287 |
if (array_int_len == 8 && buf_int_len == 8 && len == 1) { |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
288 |
struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; |
899 | 289 |
uint8_t *ip = la->la_array; |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
290 |
uint64_t *buf64 = buf; |
899 | 291 |
|
292 |
*buf64 = (uint64_t)ip[0] << 56 | (uint64_t)ip[1] << 48 | |
|
293 |
(uint64_t)ip[2] << 40 | (uint64_t)ip[3] << 32 | |
|
294 |
(uint64_t)ip[4] << 24 | (uint64_t)ip[5] << 16 | |
|
295 |
(uint64_t)ip[6] << 8 | (uint64_t)ip[7]; |
|
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
296 |
return; |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
297 |
} |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
298 |
|
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
299 |
/* Fast path for an array of 1-byte integers (eg. the entry name) */ |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
300 |
if (array_int_len == 1 && buf_int_len == 1 && |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
301 |
buf_len > array_len + ZAP_LEAF_ARRAY_BYTES) { |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
302 |
while (chunk != CHAIN_END) { |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
303 |
struct zap_leaf_array *la = |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
304 |
&ZAP_LEAF_CHUNK(l, chunk).l_array; |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
305 |
bcopy(la->la_array, p, ZAP_LEAF_ARRAY_BYTES); |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
306 |
p += ZAP_LEAF_ARRAY_BYTES; |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
307 |
chunk = la->la_next; |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
308 |
} |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
309 |
return; |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
310 |
} |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
311 |
|
789 | 312 |
while (len > 0) { |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
313 |
struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; |
789 | 314 |
int i; |
315 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
316 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
789 | 317 |
for (i = 0; i < ZAP_LEAF_ARRAY_BYTES && len > 0; i++) { |
318 |
value = (value << 8) | la->la_array[i]; |
|
319 |
byten++; |
|
320 |
if (byten == array_int_len) { |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
321 |
stv(buf_int_len, p, value); |
789 | 322 |
byten = 0; |
323 |
len--; |
|
324 |
if (len == 0) |
|
325 |
return; |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
326 |
p += buf_int_len; |
789 | 327 |
} |
328 |
} |
|
329 |
chunk = la->la_next; |
|
330 |
} |
|
331 |
} |
|
332 |
||
5331 | 333 |
static boolean_t |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
334 |
zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn, |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
335 |
int chunk, int array_numints) |
789 | 336 |
{ |
337 |
int bseen = 0; |
|
338 |
||
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
339 |
if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) { |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
340 |
uint64_t *thiskey; |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
341 |
boolean_t match; |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
342 |
|
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
343 |
ASSERT(zn->zn_key_intlen == sizeof (*thiskey)); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
344 |
thiskey = kmem_alloc(array_numints * sizeof (*thiskey), |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
345 |
KM_SLEEP); |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
346 |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
347 |
zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints, |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
348 |
sizeof (*thiskey), array_numints, thiskey); |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
349 |
match = bcmp(thiskey, zn->zn_key_orig, |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
350 |
array_numints * sizeof (*thiskey)) == 0; |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
351 |
kmem_free(thiskey, array_numints * sizeof (*thiskey)); |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
352 |
return (match); |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
353 |
} |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
354 |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
355 |
ASSERT(zn->zn_key_intlen == 1); |
5331 | 356 |
if (zn->zn_matchtype == MT_FIRST) { |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
357 |
char *thisname = kmem_alloc(array_numints, KM_SLEEP); |
5331 | 358 |
boolean_t match; |
359 |
||
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
360 |
zap_leaf_array_read(l, chunk, sizeof (char), array_numints, |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
361 |
sizeof (char), array_numints, thisname); |
5331 | 362 |
match = zap_match(zn, thisname); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
363 |
kmem_free(thisname, array_numints); |
5331 | 364 |
return (match); |
365 |
} |
|
366 |
||
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
367 |
/* |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
368 |
* Fast path for exact matching. |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
369 |
* First check that the lengths match, so that we don't read |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
370 |
* past the end of the zn_key_orig array. |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
371 |
*/ |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
372 |
if (array_numints != zn->zn_key_orig_numints) |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
373 |
return (B_FALSE); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
374 |
while (bseen < array_numints) { |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
375 |
struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array; |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
376 |
int toread = MIN(array_numints - bseen, ZAP_LEAF_ARRAY_BYTES); |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
377 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
378 |
if (bcmp(la->la_array, (char *)zn->zn_key_orig + bseen, toread)) |
789 | 379 |
break; |
380 |
chunk = la->la_next; |
|
381 |
bseen += toread; |
|
382 |
} |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
383 |
return (bseen == array_numints); |
789 | 384 |
} |
385 |
||
386 |
/* |
|
387 |
* Routines which manipulate leaf entries. |
|
388 |
*/ |
|
389 |
||
390 |
int |
|
5331 | 391 |
zap_leaf_lookup(zap_leaf_t *l, zap_name_t *zn, zap_entry_handle_t *zeh) |
789 | 392 |
{ |
393 |
uint16_t *chunkp; |
|
394 |
struct zap_leaf_entry *le; |
|
395 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
396 |
ASSERT3U(l->l_phys->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC); |
789 | 397 |
|
5331 | 398 |
again: |
399 |
for (chunkp = LEAF_HASH_ENTPTR(l, zn->zn_hash); |
|
789 | 400 |
*chunkp != CHAIN_END; chunkp = &le->le_next) { |
401 |
uint16_t chunk = *chunkp; |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
402 |
le = ZAP_LEAF_ENTRY(l, chunk); |
789 | 403 |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
404 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
405 |
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); |
789 | 406 |
|
5331 | 407 |
if (le->le_hash != zn->zn_hash) |
789 | 408 |
continue; |
409 |
||
5331 | 410 |
/* |
411 |
* NB: the entry chain is always sorted by cd on |
|
412 |
* normalized zap objects, so this will find the |
|
413 |
* lowest-cd match for MT_FIRST. |
|
414 |
*/ |
|
415 |
ASSERT(zn->zn_matchtype == MT_EXACT || |
|
416 |
(l->l_phys->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED)); |
|
417 |
if (zap_leaf_array_match(l, zn, le->le_name_chunk, |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
418 |
le->le_name_numints)) { |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
419 |
zeh->zeh_num_integers = le->le_value_numints; |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
420 |
zeh->zeh_integer_size = le->le_value_intlen; |
789 | 421 |
zeh->zeh_cd = le->le_cd; |
422 |
zeh->zeh_hash = le->le_hash; |
|
423 |
zeh->zeh_chunkp = chunkp; |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
424 |
zeh->zeh_leaf = l; |
789 | 425 |
return (0); |
426 |
} |
|
427 |
} |
|
428 |
||
5331 | 429 |
/* |
430 |
* NB: we could of course do this in one pass, but that would be |
|
431 |
* a pain. We'll see if MT_BEST is even used much. |
|
432 |
*/ |
|
433 |
if (zn->zn_matchtype == MT_BEST) { |
|
434 |
zn->zn_matchtype = MT_FIRST; |
|
435 |
goto again; |
|
436 |
} |
|
437 |
||
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
438 |
return (SET_ERROR(ENOENT)); |
789 | 439 |
} |
440 |
||
441 |
/* Return (h1,cd1 >= h2,cd2) */ |
|
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
442 |
#define HCD_GTEQ(h1, cd1, h2, cd2) \ |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
443 |
((h1 > h2) ? TRUE : ((h1 == h2 && cd1 >= cd2) ? TRUE : FALSE)) |
789 | 444 |
|
445 |
int |
|
446 |
zap_leaf_lookup_closest(zap_leaf_t *l, |
|
447 |
uint64_t h, uint32_t cd, zap_entry_handle_t *zeh) |
|
448 |
{ |
|
449 |
uint16_t chunk; |
|
450 |
uint64_t besth = -1ULL; |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
451 |
uint32_t bestcd = -1U; |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
452 |
uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES(l)-1; |
789 | 453 |
uint16_t lh; |
454 |
struct zap_leaf_entry *le; |
|
455 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
456 |
ASSERT3U(l->l_phys->l_hdr.lh_magic, ==, ZAP_LEAF_MAGIC); |
789 | 457 |
|
458 |
for (lh = LEAF_HASH(l, h); lh <= bestlh; lh++) { |
|
459 |
for (chunk = l->l_phys->l_hash[lh]; |
|
460 |
chunk != CHAIN_END; chunk = le->le_next) { |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
461 |
le = ZAP_LEAF_ENTRY(l, chunk); |
789 | 462 |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
463 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
464 |
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); |
789 | 465 |
|
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
466 |
if (HCD_GTEQ(le->le_hash, le->le_cd, h, cd) && |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
789
diff
changeset
|
467 |
HCD_GTEQ(besth, bestcd, le->le_hash, le->le_cd)) { |
789 | 468 |
ASSERT3U(bestlh, >=, lh); |
469 |
bestlh = lh; |
|
470 |
besth = le->le_hash; |
|
471 |
bestcd = le->le_cd; |
|
472 |
||
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
473 |
zeh->zeh_num_integers = le->le_value_numints; |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
474 |
zeh->zeh_integer_size = le->le_value_intlen; |
789 | 475 |
zeh->zeh_cd = le->le_cd; |
476 |
zeh->zeh_hash = le->le_hash; |
|
477 |
zeh->zeh_fakechunk = chunk; |
|
478 |
zeh->zeh_chunkp = &zeh->zeh_fakechunk; |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
479 |
zeh->zeh_leaf = l; |
789 | 480 |
} |
481 |
} |
|
482 |
} |
|
483 |
||
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
484 |
return (bestcd == -1U ? ENOENT : 0); |
789 | 485 |
} |
486 |
||
487 |
int |
|
488 |
zap_entry_read(const zap_entry_handle_t *zeh, |
|
489 |
uint8_t integer_size, uint64_t num_integers, void *buf) |
|
490 |
{ |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
491 |
struct zap_leaf_entry *le = |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
492 |
ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp); |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
493 |
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); |
789 | 494 |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
495 |
if (le->le_value_intlen > integer_size) |
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
496 |
return (SET_ERROR(EINVAL)); |
789 | 497 |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
498 |
zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk, |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
499 |
le->le_value_intlen, le->le_value_numints, |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
500 |
integer_size, num_integers, buf); |
789 | 501 |
|
502 |
if (zeh->zeh_num_integers > num_integers) |
|
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
503 |
return (SET_ERROR(EOVERFLOW)); |
789 | 504 |
return (0); |
505 |
||
506 |
} |
|
507 |
||
508 |
int |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
509 |
zap_entry_read_name(zap_t *zap, const zap_entry_handle_t *zeh, uint16_t buflen, |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
510 |
char *buf) |
789 | 511 |
{ |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
512 |
struct zap_leaf_entry *le = |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
513 |
ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp); |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
514 |
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); |
789 | 515 |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
516 |
if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) { |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
517 |
zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 8, |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
518 |
le->le_name_numints, 8, buflen / 8, buf); |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
519 |
} else { |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
520 |
zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1, |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
521 |
le->le_name_numints, 1, buflen, buf); |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
522 |
} |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
523 |
if (le->le_name_numints > buflen) |
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
524 |
return (SET_ERROR(EOVERFLOW)); |
789 | 525 |
return (0); |
526 |
} |
|
527 |
||
528 |
int |
|
529 |
zap_entry_update(zap_entry_handle_t *zeh, |
|
530 |
uint8_t integer_size, uint64_t num_integers, const void *buf) |
|
531 |
{ |
|
532 |
int delta_chunks; |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
533 |
zap_leaf_t *l = zeh->zeh_leaf; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
534 |
struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, *zeh->zeh_chunkp); |
789 | 535 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
536 |
delta_chunks = ZAP_LEAF_ARRAY_NCHUNKS(num_integers * integer_size) - |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
537 |
ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * le->le_value_intlen); |
789 | 538 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
539 |
if ((int)l->l_phys->l_hdr.lh_nfree < delta_chunks) |
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
540 |
return (SET_ERROR(EAGAIN)); |
789 | 541 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
542 |
zap_leaf_array_free(l, &le->le_value_chunk); |
789 | 543 |
le->le_value_chunk = |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
544 |
zap_leaf_array_create(l, buf, integer_size, num_integers); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
545 |
le->le_value_numints = num_integers; |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
546 |
le->le_value_intlen = integer_size; |
789 | 547 |
return (0); |
548 |
} |
|
549 |
||
550 |
void |
|
551 |
zap_entry_remove(zap_entry_handle_t *zeh) |
|
552 |
{ |
|
553 |
uint16_t entry_chunk; |
|
554 |
struct zap_leaf_entry *le; |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
555 |
zap_leaf_t *l = zeh->zeh_leaf; |
789 | 556 |
|
557 |
ASSERT3P(zeh->zeh_chunkp, !=, &zeh->zeh_fakechunk); |
|
558 |
||
559 |
entry_chunk = *zeh->zeh_chunkp; |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
560 |
le = ZAP_LEAF_ENTRY(l, entry_chunk); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
561 |
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); |
789 | 562 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
563 |
zap_leaf_array_free(l, &le->le_name_chunk); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
564 |
zap_leaf_array_free(l, &le->le_value_chunk); |
789 | 565 |
|
566 |
*zeh->zeh_chunkp = le->le_next; |
|
567 |
zap_leaf_chunk_free(l, entry_chunk); |
|
568 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
569 |
l->l_phys->l_hdr.lh_nentries--; |
789 | 570 |
} |
571 |
||
572 |
int |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
573 |
zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd, |
789 | 574 |
uint8_t integer_size, uint64_t num_integers, const void *buf, |
575 |
zap_entry_handle_t *zeh) |
|
576 |
{ |
|
577 |
uint16_t chunk; |
|
578 |
uint16_t *chunkp; |
|
579 |
struct zap_leaf_entry *le; |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
580 |
uint64_t valuelen; |
789 | 581 |
int numchunks; |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
582 |
uint64_t h = zn->zn_hash; |
789 | 583 |
|
584 |
valuelen = integer_size * num_integers; |
|
585 |
||
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
586 |
numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints * |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
587 |
zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen); |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
588 |
if (numchunks > ZAP_LEAF_NUMCHUNKS(l)) |
789 | 589 |
return (E2BIG); |
590 |
||
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
591 |
if (cd == ZAP_NEED_CD) { |
5331 | 592 |
/* find the lowest unused cd */ |
593 |
if (l->l_phys->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) { |
|
594 |
cd = 0; |
|
595 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
596 |
for (chunk = *LEAF_HASH_ENTPTR(l, h); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
597 |
chunk != CHAIN_END; chunk = le->le_next) { |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
598 |
le = ZAP_LEAF_ENTRY(l, chunk); |
5331 | 599 |
if (le->le_cd > cd) |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
600 |
break; |
5331 | 601 |
if (le->le_hash == h) { |
602 |
ASSERT3U(cd, ==, le->le_cd); |
|
603 |
cd++; |
|
789 | 604 |
} |
605 |
} |
|
5331 | 606 |
} else { |
607 |
/* old unsorted format; do it the O(n^2) way */ |
|
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
608 |
for (cd = 0; ; cd++) { |
5331 | 609 |
for (chunk = *LEAF_HASH_ENTPTR(l, h); |
610 |
chunk != CHAIN_END; chunk = le->le_next) { |
|
611 |
le = ZAP_LEAF_ENTRY(l, chunk); |
|
612 |
if (le->le_hash == h && |
|
613 |
le->le_cd == cd) { |
|
614 |
break; |
|
615 |
} |
|
616 |
} |
|
617 |
/* If this cd is not in use, we are good. */ |
|
618 |
if (chunk == CHAIN_END) |
|
619 |
break; |
|
620 |
} |
|
789 | 621 |
} |
5331 | 622 |
/* |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
623 |
* We would run out of space in a block before we could |
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
624 |
* store enough entries to run out of CD values. |
5331 | 625 |
*/ |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
626 |
ASSERT3U(cd, <, zap_maxcd(zn->zn_zap)); |
789 | 627 |
} |
628 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
629 |
if (l->l_phys->l_hdr.lh_nfree < numchunks) |
13980
d7059eb1884c
3598 want to dtrace when errors are generated in zfs
Matthew Ahrens <mahrens@delphix.com>
parents:
13952
diff
changeset
|
630 |
return (SET_ERROR(EAGAIN)); |
789 | 631 |
|
632 |
/* make the entry */ |
|
633 |
chunk = zap_leaf_chunk_alloc(l); |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
634 |
le = ZAP_LEAF_ENTRY(l, chunk); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
635 |
le->le_type = ZAP_CHUNK_ENTRY; |
10922
e2081f502306
PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents:
9643
diff
changeset
|
636 |
le->le_name_chunk = zap_leaf_array_create(l, zn->zn_key_orig, |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
637 |
zn->zn_key_intlen, zn->zn_key_orig_numints); |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
638 |
le->le_name_numints = zn->zn_key_orig_numints; |
789 | 639 |
le->le_value_chunk = |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
640 |
zap_leaf_array_create(l, buf, integer_size, num_integers); |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
641 |
le->le_value_numints = num_integers; |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
642 |
le->le_value_intlen = integer_size; |
789 | 643 |
le->le_hash = h; |
644 |
le->le_cd = cd; |
|
645 |
||
646 |
/* link it into the hash chain */ |
|
5331 | 647 |
/* XXX if we did the search above, we could just use that */ |
648 |
chunkp = zap_leaf_rehash_entry(l, chunk); |
|
789 | 649 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
650 |
l->l_phys->l_hdr.lh_nentries++; |
789 | 651 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
652 |
zeh->zeh_leaf = l; |
789 | 653 |
zeh->zeh_num_integers = num_integers; |
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
654 |
zeh->zeh_integer_size = le->le_value_intlen; |
789 | 655 |
zeh->zeh_cd = le->le_cd; |
656 |
zeh->zeh_hash = le->le_hash; |
|
657 |
zeh->zeh_chunkp = chunkp; |
|
658 |
||
659 |
return (0); |
|
660 |
} |
|
661 |
||
662 |
/* |
|
5331 | 663 |
* Determine if there is another entry with the same normalized form. |
664 |
* For performance purposes, either zn or name must be provided (the |
|
665 |
* other can be NULL). Note, there usually won't be any hash |
|
666 |
* conflicts, in which case we don't need the concatenated/normalized |
|
667 |
* form of the name. But all callers have one of these on hand anyway, |
|
668 |
* so might as well take advantage. A cleaner but slower interface |
|
669 |
* would accept neither argument, and compute the normalized name as |
|
670 |
* needed (using zap_name_alloc(zap_entry_read_name(zeh))). |
|
671 |
*/ |
|
672 |
boolean_t |
|
673 |
zap_entry_normalization_conflict(zap_entry_handle_t *zeh, zap_name_t *zn, |
|
674 |
const char *name, zap_t *zap) |
|
675 |
{ |
|
676 |
uint64_t chunk; |
|
677 |
struct zap_leaf_entry *le; |
|
678 |
boolean_t allocdzn = B_FALSE; |
|
679 |
||
680 |
if (zap->zap_normflags == 0) |
|
681 |
return (B_FALSE); |
|
682 |
||
683 |
for (chunk = *LEAF_HASH_ENTPTR(zeh->zeh_leaf, zeh->zeh_hash); |
|
684 |
chunk != CHAIN_END; chunk = le->le_next) { |
|
685 |
le = ZAP_LEAF_ENTRY(zeh->zeh_leaf, chunk); |
|
686 |
if (le->le_hash != zeh->zeh_hash) |
|
687 |
continue; |
|
688 |
if (le->le_cd == zeh->zeh_cd) |
|
689 |
continue; |
|
690 |
||
691 |
if (zn == NULL) { |
|
692 |
zn = zap_name_alloc(zap, name, MT_FIRST); |
|
693 |
allocdzn = B_TRUE; |
|
694 |
} |
|
695 |
if (zap_leaf_array_match(zeh->zeh_leaf, zn, |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
696 |
le->le_name_chunk, le->le_name_numints)) { |
5331 | 697 |
if (allocdzn) |
698 |
zap_name_free(zn); |
|
699 |
return (B_TRUE); |
|
700 |
} |
|
701 |
} |
|
702 |
if (allocdzn) |
|
703 |
zap_name_free(zn); |
|
704 |
return (B_FALSE); |
|
705 |
} |
|
706 |
||
707 |
/* |
|
789 | 708 |
* Routines for transferring entries between leafs. |
709 |
*/ |
|
710 |
||
5331 | 711 |
static uint16_t * |
789 | 712 |
zap_leaf_rehash_entry(zap_leaf_t *l, uint16_t entry) |
713 |
{ |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
714 |
struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, entry); |
5331 | 715 |
struct zap_leaf_entry *le2; |
716 |
uint16_t *chunkp; |
|
717 |
||
718 |
/* |
|
719 |
* keep the entry chain sorted by cd |
|
720 |
* NB: this will not cause problems for unsorted leafs, though |
|
721 |
* it is unnecessary there. |
|
722 |
*/ |
|
723 |
for (chunkp = LEAF_HASH_ENTPTR(l, le->le_hash); |
|
724 |
*chunkp != CHAIN_END; chunkp = &le2->le_next) { |
|
725 |
le2 = ZAP_LEAF_ENTRY(l, *chunkp); |
|
726 |
if (le2->le_cd > le->le_cd) |
|
727 |
break; |
|
728 |
} |
|
729 |
||
730 |
le->le_next = *chunkp; |
|
731 |
*chunkp = entry; |
|
732 |
return (chunkp); |
|
789 | 733 |
} |
734 |
||
735 |
static uint16_t |
|
736 |
zap_leaf_transfer_array(zap_leaf_t *l, uint16_t chunk, zap_leaf_t *nl) |
|
737 |
{ |
|
738 |
uint16_t new_chunk; |
|
739 |
uint16_t *nchunkp = &new_chunk; |
|
740 |
||
741 |
while (chunk != CHAIN_END) { |
|
742 |
uint16_t nchunk = zap_leaf_chunk_alloc(nl); |
|
743 |
struct zap_leaf_array *nla = |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
744 |
&ZAP_LEAF_CHUNK(nl, nchunk).l_array; |
789 | 745 |
struct zap_leaf_array *la = |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
746 |
&ZAP_LEAF_CHUNK(l, chunk).l_array; |
789 | 747 |
int nextchunk = la->la_next; |
748 |
||
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
749 |
ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
750 |
ASSERT3U(nchunk, <, ZAP_LEAF_NUMCHUNKS(l)); |
789 | 751 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
752 |
*nla = *la; /* structure assignment */ |
789 | 753 |
|
754 |
zap_leaf_chunk_free(l, chunk); |
|
755 |
chunk = nextchunk; |
|
756 |
*nchunkp = nchunk; |
|
757 |
nchunkp = &nla->la_next; |
|
758 |
} |
|
759 |
*nchunkp = CHAIN_END; |
|
760 |
return (new_chunk); |
|
761 |
} |
|
762 |
||
763 |
static void |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
764 |
zap_leaf_transfer_entry(zap_leaf_t *l, int entry, zap_leaf_t *nl) |
789 | 765 |
{ |
766 |
struct zap_leaf_entry *le, *nle; |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
767 |
uint16_t chunk; |
789 | 768 |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
769 |
le = ZAP_LEAF_ENTRY(l, entry); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
770 |
ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY); |
789 | 771 |
|
772 |
chunk = zap_leaf_chunk_alloc(nl); |
|
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
773 |
nle = ZAP_LEAF_ENTRY(nl, chunk); |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
774 |
*nle = *le; /* structure assignment */ |
789 | 775 |
|
5331 | 776 |
(void) zap_leaf_rehash_entry(nl, chunk); |
789 | 777 |
|
778 |
nle->le_name_chunk = zap_leaf_transfer_array(l, le->le_name_chunk, nl); |
|
779 |
nle->le_value_chunk = |
|
780 |
zap_leaf_transfer_array(l, le->le_value_chunk, nl); |
|
781 |
||
782 |
zap_leaf_chunk_free(l, entry); |
|
783 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
784 |
l->l_phys->l_hdr.lh_nentries--; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
785 |
nl->l_phys->l_hdr.lh_nentries++; |
789 | 786 |
} |
787 |
||
788 |
/* |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
789 |
* Transfer the entries whose hash prefix ends in 1 to the new leaf. |
789 | 790 |
*/ |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
791 |
void |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5331
diff
changeset
|
792 |
zap_leaf_split(zap_leaf_t *l, zap_leaf_t *nl, boolean_t sort) |
789 | 793 |
{ |
794 |
int i; |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
795 |
int bit = 64 - 1 - l->l_phys->l_hdr.lh_prefix_len; |
789 | 796 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
797 |
/* set new prefix and prefix_len */ |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
798 |
l->l_phys->l_hdr.lh_prefix <<= 1; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
799 |
l->l_phys->l_hdr.lh_prefix_len++; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
800 |
nl->l_phys->l_hdr.lh_prefix = l->l_phys->l_hdr.lh_prefix | 1; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
801 |
nl->l_phys->l_hdr.lh_prefix_len = l->l_phys->l_hdr.lh_prefix_len; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
802 |
|
789 | 803 |
/* break existing hash chains */ |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
804 |
zap_memset(l->l_phys->l_hash, CHAIN_END, 2*ZAP_LEAF_HASH_NUMENTRIES(l)); |
789 | 805 |
|
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5331
diff
changeset
|
806 |
if (sort) |
5331 | 807 |
l->l_phys->l_hdr.lh_flags |= ZLF_ENTRIES_CDSORTED; |
808 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
809 |
/* |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
810 |
* Transfer entries whose hash bit 'bit' is set to nl; rehash |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
811 |
* the remaining entries |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
812 |
* |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
813 |
* NB: We could find entries via the hashtable instead. That |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
814 |
* would be O(hashents+numents) rather than O(numblks+numents), |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
815 |
* but this accesses memory more sequentially, and when we're |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
816 |
* called, the block is usually pretty full. |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
817 |
*/ |
1491
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
818 |
for (i = 0; i < ZAP_LEAF_NUMCHUNKS(l); i++) { |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
819 |
struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, i); |
bdcb30e07e7d
6389368 fat zap should use 16k blocks (with backwards compatability)
ahrens
parents:
899
diff
changeset
|
820 |
if (le->le_type != ZAP_CHUNK_ENTRY) |
789 | 821 |
continue; |
822 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
823 |
if (le->le_hash & (1ULL << bit)) |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
824 |
zap_leaf_transfer_entry(l, i, nl); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
825 |
else |
5331 | 826 |
(void) zap_leaf_rehash_entry(l, i); |
789 | 827 |
} |
828 |
} |
|
829 |
||
830 |
void |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
831 |
zap_leaf_stats(zap_t *zap, zap_leaf_t *l, zap_stats_t *zs) |
789 | 832 |
{ |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
833 |
int i, n; |
789 | 834 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
835 |
n = zap->zap_f.zap_phys->zap_ptrtbl.zt_shift - |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
836 |
l->l_phys->l_hdr.lh_prefix_len; |
789 | 837 |
n = MIN(n, ZAP_HISTOGRAM_SIZE-1); |
838 |
zs->zs_leafs_with_2n_pointers[n]++; |
|
839 |
||
840 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
841 |
n = l->l_phys->l_hdr.lh_nentries/5; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
842 |
n = MIN(n, ZAP_HISTOGRAM_SIZE-1); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
843 |
zs->zs_blocks_with_n5_entries[n]++; |
789 | 844 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
845 |
n = ((1<<FZAP_BLOCK_SHIFT(zap)) - |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
846 |
l->l_phys->l_hdr.lh_nfree * (ZAP_LEAF_ARRAY_BYTES+1))*10 / |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
847 |
(1<<FZAP_BLOCK_SHIFT(zap)); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
848 |
n = MIN(n, ZAP_HISTOGRAM_SIZE-1); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
849 |
zs->zs_blocks_n_tenths_full[n]++; |
789 | 850 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
851 |
for (i = 0; i < ZAP_LEAF_HASH_NUMENTRIES(l); i++) { |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
852 |
int nentries = 0; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
853 |
int chunk = l->l_phys->l_hash[i]; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
854 |
|
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
855 |
while (chunk != CHAIN_END) { |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
856 |
struct zap_leaf_entry *le = |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
857 |
ZAP_LEAF_ENTRY(l, chunk); |
789 | 858 |
|
11165
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
859 |
n = 1 + ZAP_LEAF_ARRAY_NCHUNKS(le->le_name_numints) + |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
860 |
ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * |
68184eb5449e
6903705 dedup=fletcher4,verify doesn't byteswap correctly, has lots of hash collisions
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
10922
diff
changeset
|
861 |
le->le_value_intlen); |
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
862 |
n = MIN(n, ZAP_HISTOGRAM_SIZE-1); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
863 |
zs->zs_entries_using_n_chunks[n]++; |
789 | 864 |
|
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
865 |
chunk = le->le_next; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
866 |
nentries++; |
789 | 867 |
} |
868 |
||
1578
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
869 |
n = nentries; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
870 |
n = MIN(n, ZAP_HISTOGRAM_SIZE-1); |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
871 |
zs->zs_buckets_with_n_entries[n]++; |
1fd8ab638fc0
6389897 remove zap leaf chaining code as it is never used
ahrens
parents:
1491
diff
changeset
|
872 |
} |
789 | 873 |
} |