]>
Commit | Line | Data |
---|---|---|
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 (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
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 | /* | |
22 | * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | |
23 | * Copyright (c) 2013, Delphix. All rights reserved. | |
24 | * Copyright (c) 2013, Saso Kiselkov. All rights reserved. | |
25 | * Copyright (c) 2013, Nexenta Systems, Inc. All rights reserved. | |
26 | * Copyright (c) 2020, George Amanakis. All rights reserved. | |
27 | */ | |
28 | ||
29 | #ifndef _SYS_ARC_IMPL_H | |
30 | #define _SYS_ARC_IMPL_H | |
31 | ||
32 | #include <sys/arc.h> | |
33 | #include <sys/zio_crypt.h> | |
34 | #include <sys/zthr.h> | |
35 | #include <sys/aggsum.h> | |
36 | ||
37 | #ifdef __cplusplus | |
38 | extern "C" { | |
39 | #endif | |
40 | ||
41 | /* | |
42 | * Note that buffers can be in one of 6 states: | |
43 | * ARC_anon - anonymous (discussed below) | |
44 | * ARC_mru - recently used, currently cached | |
45 | * ARC_mru_ghost - recently used, no longer in cache | |
46 | * ARC_mfu - frequently used, currently cached | |
47 | * ARC_mfu_ghost - frequently used, no longer in cache | |
48 | * ARC_l2c_only - exists in L2ARC but not other states | |
49 | * When there are no active references to the buffer, they are | |
50 | * are linked onto a list in one of these arc states. These are | |
51 | * the only buffers that can be evicted or deleted. Within each | |
52 | * state there are multiple lists, one for meta-data and one for | |
53 | * non-meta-data. Meta-data (indirect blocks, blocks of dnodes, | |
54 | * etc.) is tracked separately so that it can be managed more | |
55 | * explicitly: favored over data, limited explicitly. | |
56 | * | |
57 | * Anonymous buffers are buffers that are not associated with | |
58 | * a DVA. These are buffers that hold dirty block copies | |
59 | * before they are written to stable storage. By definition, | |
60 | * they are "ref'd" and are considered part of arc_mru | |
61 | * that cannot be freed. Generally, they will acquire a DVA | |
62 | * as they are written and migrate onto the arc_mru list. | |
63 | * | |
64 | * The ARC_l2c_only state is for buffers that are in the second | |
65 | * level ARC but no longer in any of the ARC_m* lists. The second | |
66 | * level ARC itself may also contain buffers that are in any of | |
67 | * the ARC_m* states - meaning that a buffer can exist in two | |
68 | * places. The reason for the ARC_l2c_only state is to keep the | |
69 | * buffer header in the hash table, so that reads that hit the | |
70 | * second level ARC benefit from these fast lookups. | |
71 | */ | |
72 | ||
73 | typedef struct arc_state { | |
74 | /* | |
75 | * list of evictable buffers | |
76 | */ | |
77 | multilist_t *arcs_list[ARC_BUFC_NUMTYPES]; | |
78 | /* | |
79 | * total amount of evictable data in this state | |
80 | */ | |
81 | zfs_refcount_t arcs_esize[ARC_BUFC_NUMTYPES]; | |
82 | /* | |
83 | * total amount of data in this state; this includes: evictable, | |
84 | * non-evictable, ARC_BUFC_DATA, and ARC_BUFC_METADATA. | |
85 | */ | |
86 | zfs_refcount_t arcs_size; | |
87 | /* | |
88 | * supports the "dbufs" kstat | |
89 | */ | |
90 | arc_state_type_t arcs_state; | |
91 | } arc_state_t; | |
92 | ||
93 | typedef struct arc_callback arc_callback_t; | |
94 | ||
95 | struct arc_callback { | |
96 | void *acb_private; | |
97 | arc_read_done_func_t *acb_done; | |
98 | arc_buf_t *acb_buf; | |
99 | boolean_t acb_encrypted; | |
100 | boolean_t acb_compressed; | |
101 | boolean_t acb_noauth; | |
102 | zbookmark_phys_t acb_zb; | |
103 | zio_t *acb_zio_dummy; | |
104 | zio_t *acb_zio_head; | |
105 | arc_callback_t *acb_next; | |
106 | }; | |
107 | ||
108 | typedef struct arc_write_callback arc_write_callback_t; | |
109 | ||
110 | struct arc_write_callback { | |
111 | void *awcb_private; | |
112 | arc_write_done_func_t *awcb_ready; | |
113 | arc_write_done_func_t *awcb_children_ready; | |
114 | arc_write_done_func_t *awcb_physdone; | |
115 | arc_write_done_func_t *awcb_done; | |
116 | arc_buf_t *awcb_buf; | |
117 | }; | |
118 | ||
119 | /* | |
120 | * ARC buffers are separated into multiple structs as a memory saving measure: | |
121 | * - Common fields struct, always defined, and embedded within it: | |
122 | * - L2-only fields, always allocated but undefined when not in L2ARC | |
123 | * - L1-only fields, only allocated when in L1ARC | |
124 | * | |
125 | * Buffer in L1 Buffer only in L2 | |
126 | * +------------------------+ +------------------------+ | |
127 | * | arc_buf_hdr_t | | arc_buf_hdr_t | | |
128 | * | | | | | |
129 | * | | | | | |
130 | * | | | | | |
131 | * +------------------------+ +------------------------+ | |
132 | * | l2arc_buf_hdr_t | | l2arc_buf_hdr_t | | |
133 | * | (undefined if L1-only) | | | | |
134 | * +------------------------+ +------------------------+ | |
135 | * | l1arc_buf_hdr_t | | |
136 | * | | | |
137 | * | | | |
138 | * | | | |
139 | * | | | |
140 | * +------------------------+ | |
141 | * | |
142 | * Because it's possible for the L2ARC to become extremely large, we can wind | |
143 | * up eating a lot of memory in L2ARC buffer headers, so the size of a header | |
144 | * is minimized by only allocating the fields necessary for an L1-cached buffer | |
145 | * when a header is actually in the L1 cache. The sub-headers (l1arc_buf_hdr and | |
146 | * l2arc_buf_hdr) are embedded rather than allocated separately to save a couple | |
147 | * words in pointers. arc_hdr_realloc() is used to switch a header between | |
148 | * these two allocation states. | |
149 | */ | |
150 | typedef struct l1arc_buf_hdr { | |
151 | kmutex_t b_freeze_lock; | |
152 | zio_cksum_t *b_freeze_cksum; | |
153 | ||
154 | arc_buf_t *b_buf; | |
155 | uint32_t b_bufcnt; | |
156 | /* for waiting on writes to complete */ | |
157 | kcondvar_t b_cv; | |
158 | uint8_t b_byteswap; | |
159 | ||
160 | ||
161 | /* protected by arc state mutex */ | |
162 | arc_state_t *b_state; | |
163 | multilist_node_t b_arc_node; | |
164 | ||
165 | /* updated atomically */ | |
166 | clock_t b_arc_access; | |
167 | uint32_t b_mru_hits; | |
168 | uint32_t b_mru_ghost_hits; | |
169 | uint32_t b_mfu_hits; | |
170 | uint32_t b_mfu_ghost_hits; | |
171 | uint32_t b_l2_hits; | |
172 | ||
173 | /* self protecting */ | |
174 | zfs_refcount_t b_refcnt; | |
175 | ||
176 | arc_callback_t *b_acb; | |
177 | abd_t *b_pabd; | |
178 | } l1arc_buf_hdr_t; | |
179 | ||
180 | typedef enum l2arc_dev_hdr_flags_t { | |
181 | L2ARC_DEV_HDR_EVICT_FIRST = (1 << 0) /* mirror of l2ad_first */ | |
182 | } l2arc_dev_hdr_flags_t; | |
183 | ||
184 | /* | |
185 | * Pointer used in persistent L2ARC (for pointing to log blocks). | |
186 | */ | |
187 | typedef struct l2arc_log_blkptr { | |
188 | /* | |
189 | * Offset of log block within the device, in bytes | |
190 | */ | |
191 | uint64_t lbp_daddr; | |
192 | /* | |
193 | * Aligned payload size (in bytes) of the log block | |
194 | */ | |
195 | uint64_t lbp_payload_asize; | |
196 | /* | |
197 | * Offset in bytes of the first buffer in the payload | |
198 | */ | |
199 | uint64_t lbp_payload_start; | |
200 | /* | |
201 | * lbp_prop has the following format: | |
202 | * * logical size (in bytes) | |
203 | * * aligned (after compression) size (in bytes) | |
204 | * * compression algorithm (we always LZ4-compress l2arc logs) | |
205 | * * checksum algorithm (used for lbp_cksum) | |
206 | */ | |
207 | uint64_t lbp_prop; | |
208 | zio_cksum_t lbp_cksum; /* checksum of log */ | |
209 | } l2arc_log_blkptr_t; | |
210 | ||
211 | /* | |
212 | * The persistent L2ARC device header. | |
213 | * Byte order of magic determines whether 64-bit bswap of fields is necessary. | |
214 | */ | |
215 | typedef struct l2arc_dev_hdr_phys { | |
216 | uint64_t dh_magic; /* L2ARC_DEV_HDR_MAGIC */ | |
217 | uint64_t dh_version; /* Persistent L2ARC version */ | |
218 | ||
219 | /* | |
220 | * Global L2ARC device state and metadata. | |
221 | */ | |
222 | uint64_t dh_spa_guid; | |
223 | uint64_t dh_vdev_guid; | |
224 | uint64_t dh_log_entries; /* mirror of l2ad_log_entries */ | |
225 | uint64_t dh_evict; /* evicted offset in bytes */ | |
226 | uint64_t dh_flags; /* l2arc_dev_hdr_flags_t */ | |
227 | /* | |
228 | * Used in zdb.c for determining if a log block is valid, in the same | |
229 | * way that l2arc_rebuild() does. | |
230 | */ | |
231 | uint64_t dh_start; /* mirror of l2ad_start */ | |
232 | uint64_t dh_end; /* mirror of l2ad_end */ | |
233 | /* | |
234 | * Start of log block chain. [0] -> newest log, [1] -> one older (used | |
235 | * for initiating prefetch). | |
236 | */ | |
237 | l2arc_log_blkptr_t dh_start_lbps[2]; | |
238 | /* | |
239 | * Aligned size of all log blocks as accounted by vdev_space_update(). | |
240 | */ | |
241 | uint64_t dh_lb_asize; /* mirror of l2ad_lb_asize */ | |
242 | uint64_t dh_lb_count; /* mirror of l2ad_lb_count */ | |
243 | /* | |
244 | * Mirrors of vdev_trim_action_time and vdev_trim_state, used to | |
245 | * display when the cache device was fully trimmed for the last | |
246 | * time. | |
247 | */ | |
248 | uint64_t dh_trim_action_time; | |
249 | uint64_t dh_trim_state; | |
250 | const uint64_t dh_pad[30]; /* pad to 512 bytes */ | |
251 | zio_eck_t dh_tail; | |
252 | } l2arc_dev_hdr_phys_t; | |
253 | CTASSERT_GLOBAL(sizeof (l2arc_dev_hdr_phys_t) == SPA_MINBLOCKSIZE); | |
254 | ||
255 | /* | |
256 | * A single ARC buffer header entry in a l2arc_log_blk_phys_t. | |
257 | */ | |
258 | typedef struct l2arc_log_ent_phys { | |
259 | dva_t le_dva; /* dva of buffer */ | |
260 | uint64_t le_birth; /* birth txg of buffer */ | |
261 | /* | |
262 | * le_prop has the following format: | |
263 | * * logical size (in bytes) | |
264 | * * physical (compressed) size (in bytes) | |
265 | * * compression algorithm | |
266 | * * object type (used to restore arc_buf_contents_t) | |
267 | * * protected status (used for encryption) | |
268 | * * prefetch status (used in l2arc_read_done()) | |
269 | */ | |
270 | uint64_t le_prop; | |
271 | uint64_t le_daddr; /* buf location on l2dev */ | |
272 | uint64_t le_complevel; | |
273 | /* | |
274 | * We pad the size of each entry to a power of 2 so that the size of | |
275 | * l2arc_log_blk_phys_t is power-of-2 aligned with SPA_MINBLOCKSHIFT, | |
276 | * because of the L2ARC_SET_*SIZE macros. | |
277 | */ | |
278 | const uint64_t le_pad[2]; /* pad to 64 bytes */ | |
279 | } l2arc_log_ent_phys_t; | |
280 | ||
281 | #define L2ARC_LOG_BLK_MAX_ENTRIES (1022) | |
282 | ||
283 | /* | |
284 | * A log block of up to 1022 ARC buffer log entries, chained into the | |
285 | * persistent L2ARC metadata linked list. Byte order of magic determines | |
286 | * whether 64-bit bswap of fields is necessary. | |
287 | */ | |
288 | typedef struct l2arc_log_blk_phys { | |
289 | uint64_t lb_magic; /* L2ARC_LOG_BLK_MAGIC */ | |
290 | /* | |
291 | * There are 2 chains (headed by dh_start_lbps[2]), and this field | |
292 | * points back to the previous block in this chain. We alternate | |
293 | * which chain we append to, so they are time-wise and offset-wise | |
294 | * interleaved, but that is an optimization rather than for | |
295 | * correctness. | |
296 | */ | |
297 | l2arc_log_blkptr_t lb_prev_lbp; /* pointer to prev log block */ | |
298 | /* | |
299 | * Pad header section to 128 bytes | |
300 | */ | |
301 | uint64_t lb_pad[7]; | |
302 | /* Payload */ | |
303 | l2arc_log_ent_phys_t lb_entries[L2ARC_LOG_BLK_MAX_ENTRIES]; | |
304 | } l2arc_log_blk_phys_t; /* 64K total */ | |
305 | ||
306 | /* | |
307 | * The size of l2arc_log_blk_phys_t has to be power-of-2 aligned with | |
308 | * SPA_MINBLOCKSHIFT because of L2BLK_SET_*SIZE macros. | |
309 | */ | |
310 | CTASSERT_GLOBAL(IS_P2ALIGNED(sizeof (l2arc_log_blk_phys_t), | |
311 | 1ULL << SPA_MINBLOCKSHIFT)); | |
312 | CTASSERT_GLOBAL(sizeof (l2arc_log_blk_phys_t) >= SPA_MINBLOCKSIZE); | |
313 | CTASSERT_GLOBAL(sizeof (l2arc_log_blk_phys_t) <= SPA_MAXBLOCKSIZE); | |
314 | ||
315 | /* | |
316 | * These structures hold in-flight abd buffers for log blocks as they're being | |
317 | * written to the L2ARC device. | |
318 | */ | |
319 | typedef struct l2arc_lb_abd_buf { | |
320 | abd_t *abd; | |
321 | list_node_t node; | |
322 | } l2arc_lb_abd_buf_t; | |
323 | ||
324 | /* | |
325 | * These structures hold pointers to log blocks present on the L2ARC device. | |
326 | */ | |
327 | typedef struct l2arc_lb_ptr_buf { | |
328 | l2arc_log_blkptr_t *lb_ptr; | |
329 | list_node_t node; | |
330 | } l2arc_lb_ptr_buf_t; | |
331 | ||
332 | /* Macros for setting fields in le_prop and lbp_prop */ | |
333 | #define L2BLK_GET_LSIZE(field) \ | |
334 | BF64_GET_SB((field), 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1) | |
335 | #define L2BLK_SET_LSIZE(field, x) \ | |
336 | BF64_SET_SB((field), 0, SPA_LSIZEBITS, SPA_MINBLOCKSHIFT, 1, x) | |
337 | #define L2BLK_GET_PSIZE(field) \ | |
338 | BF64_GET_SB((field), 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1) | |
339 | #define L2BLK_SET_PSIZE(field, x) \ | |
340 | BF64_SET_SB((field), 16, SPA_PSIZEBITS, SPA_MINBLOCKSHIFT, 1, x) | |
341 | #define L2BLK_GET_COMPRESS(field) \ | |
342 | BF64_GET((field), 32, SPA_COMPRESSBITS) | |
343 | #define L2BLK_SET_COMPRESS(field, x) \ | |
344 | BF64_SET((field), 32, SPA_COMPRESSBITS, x) | |
345 | #define L2BLK_GET_PREFETCH(field) BF64_GET((field), 39, 1) | |
346 | #define L2BLK_SET_PREFETCH(field, x) BF64_SET((field), 39, 1, x) | |
347 | #define L2BLK_GET_CHECKSUM(field) BF64_GET((field), 40, 8) | |
348 | #define L2BLK_SET_CHECKSUM(field, x) BF64_SET((field), 40, 8, x) | |
349 | #define L2BLK_GET_TYPE(field) BF64_GET((field), 48, 8) | |
350 | #define L2BLK_SET_TYPE(field, x) BF64_SET((field), 48, 8, x) | |
351 | #define L2BLK_GET_PROTECTED(field) BF64_GET((field), 56, 1) | |
352 | #define L2BLK_SET_PROTECTED(field, x) BF64_SET((field), 56, 1, x) | |
353 | #define L2BLK_GET_STATE(field) BF64_GET((field), 57, 4) | |
354 | #define L2BLK_SET_STATE(field, x) BF64_SET((field), 57, 4, x) | |
355 | ||
356 | #define PTR_SWAP(x, y) \ | |
357 | do { \ | |
358 | void *tmp = (x);\ | |
359 | x = y; \ | |
360 | y = tmp; \ | |
361 | _NOTE(CONSTCOND)\ | |
362 | } while (0) | |
363 | ||
364 | #define L2ARC_DEV_HDR_MAGIC 0x5a46534341434845LLU /* ASCII: "ZFSCACHE" */ | |
365 | #define L2ARC_LOG_BLK_MAGIC 0x4c4f47424c4b4844LLU /* ASCII: "LOGBLKHD" */ | |
366 | ||
367 | /* | |
368 | * L2ARC Internals | |
369 | */ | |
370 | typedef struct l2arc_dev { | |
371 | vdev_t *l2ad_vdev; /* vdev */ | |
372 | spa_t *l2ad_spa; /* spa */ | |
373 | uint64_t l2ad_hand; /* next write location */ | |
374 | uint64_t l2ad_start; /* first addr on device */ | |
375 | uint64_t l2ad_end; /* last addr on device */ | |
376 | boolean_t l2ad_first; /* first sweep through */ | |
377 | boolean_t l2ad_writing; /* currently writing */ | |
378 | kmutex_t l2ad_mtx; /* lock for buffer list */ | |
379 | list_t l2ad_buflist; /* buffer list */ | |
380 | list_node_t l2ad_node; /* device list node */ | |
381 | zfs_refcount_t l2ad_alloc; /* allocated bytes */ | |
382 | /* | |
383 | * Persistence-related stuff | |
384 | */ | |
385 | l2arc_dev_hdr_phys_t *l2ad_dev_hdr; /* persistent device header */ | |
386 | uint64_t l2ad_dev_hdr_asize; /* aligned hdr size */ | |
387 | l2arc_log_blk_phys_t l2ad_log_blk; /* currently open log block */ | |
388 | int l2ad_log_ent_idx; /* index into cur log blk */ | |
389 | /* Number of bytes in current log block's payload */ | |
390 | uint64_t l2ad_log_blk_payload_asize; | |
391 | /* | |
392 | * Offset (in bytes) of the first buffer in current log block's | |
393 | * payload. | |
394 | */ | |
395 | uint64_t l2ad_log_blk_payload_start; | |
396 | /* Flag indicating whether a rebuild is scheduled or is going on */ | |
397 | boolean_t l2ad_rebuild; | |
398 | boolean_t l2ad_rebuild_cancel; | |
399 | boolean_t l2ad_rebuild_began; | |
400 | uint64_t l2ad_log_entries; /* entries per log blk */ | |
401 | uint64_t l2ad_evict; /* evicted offset in bytes */ | |
402 | /* List of pointers to log blocks present in the L2ARC device */ | |
403 | list_t l2ad_lbptr_list; | |
404 | /* | |
405 | * Aligned size of all log blocks as accounted by vdev_space_update(). | |
406 | */ | |
407 | zfs_refcount_t l2ad_lb_asize; | |
408 | /* | |
409 | * Number of log blocks present on the device. | |
410 | */ | |
411 | zfs_refcount_t l2ad_lb_count; | |
412 | boolean_t l2ad_trim_all; /* TRIM whole device */ | |
413 | } l2arc_dev_t; | |
414 | ||
415 | /* | |
416 | * Encrypted blocks will need to be stored encrypted on the L2ARC | |
417 | * disk as they appear in the main pool. In order for this to work we | |
418 | * need to pass around the encryption parameters so they can be used | |
419 | * to write data to the L2ARC. This struct is only defined in the | |
420 | * arc_buf_hdr_t if the L1 header is defined and has the ARC_FLAG_ENCRYPTED | |
421 | * flag set. | |
422 | */ | |
423 | typedef struct arc_buf_hdr_crypt { | |
424 | abd_t *b_rabd; /* raw encrypted data */ | |
425 | dmu_object_type_t b_ot; /* object type */ | |
426 | uint32_t b_ebufcnt; /* count of encrypted buffers */ | |
427 | ||
428 | /* dsobj for looking up encryption key for l2arc encryption */ | |
429 | uint64_t b_dsobj; | |
430 | ||
431 | /* encryption parameters */ | |
432 | uint8_t b_salt[ZIO_DATA_SALT_LEN]; | |
433 | uint8_t b_iv[ZIO_DATA_IV_LEN]; | |
434 | ||
435 | /* | |
436 | * Technically this could be removed since we will always be able to | |
437 | * get the mac from the bp when we need it. However, it is inconvenient | |
438 | * for callers of arc code to have to pass a bp in all the time. This | |
439 | * also allows us to assert that L2ARC data is properly encrypted to | |
440 | * match the data in the main storage pool. | |
441 | */ | |
442 | uint8_t b_mac[ZIO_DATA_MAC_LEN]; | |
443 | } arc_buf_hdr_crypt_t; | |
444 | ||
445 | typedef struct l2arc_buf_hdr { | |
446 | /* protected by arc_buf_hdr mutex */ | |
447 | l2arc_dev_t *b_dev; /* L2ARC device */ | |
448 | uint64_t b_daddr; /* disk address, offset byte */ | |
449 | uint32_t b_hits; | |
450 | arc_state_type_t b_arcs_state; | |
451 | list_node_t b_l2node; | |
452 | } l2arc_buf_hdr_t; | |
453 | ||
454 | typedef struct l2arc_write_callback { | |
455 | l2arc_dev_t *l2wcb_dev; /* device info */ | |
456 | arc_buf_hdr_t *l2wcb_head; /* head of write buflist */ | |
457 | /* in-flight list of log blocks */ | |
458 | list_t l2wcb_abd_list; | |
459 | } l2arc_write_callback_t; | |
460 | ||
461 | struct arc_buf_hdr { | |
462 | /* protected by hash lock */ | |
463 | dva_t b_dva; | |
464 | uint64_t b_birth; | |
465 | ||
466 | arc_buf_contents_t b_type; | |
467 | uint8_t b_complevel; | |
468 | uint8_t b_reserved1; /* used for 4 byte alignment */ | |
469 | uint16_t b_reserved2; /* used for 4 byte alignment */ | |
470 | arc_buf_hdr_t *b_hash_next; | |
471 | arc_flags_t b_flags; | |
472 | ||
473 | /* | |
474 | * This field stores the size of the data buffer after | |
475 | * compression, and is set in the arc's zio completion handlers. | |
476 | * It is in units of SPA_MINBLOCKSIZE (e.g. 1 == 512 bytes). | |
477 | * | |
478 | * While the block pointers can store up to 32MB in their psize | |
479 | * field, we can only store up to 32MB minus 512B. This is due | |
480 | * to the bp using a bias of 1, whereas we use a bias of 0 (i.e. | |
481 | * a field of zeros represents 512B in the bp). We can't use a | |
482 | * bias of 1 since we need to reserve a psize of zero, here, to | |
483 | * represent holes and embedded blocks. | |
484 | * | |
485 | * This isn't a problem in practice, since the maximum size of a | |
486 | * buffer is limited to 16MB, so we never need to store 32MB in | |
487 | * this field. Even in the upstream illumos code base, the | |
488 | * maximum size of a buffer is limited to 16MB. | |
489 | */ | |
490 | uint16_t b_psize; | |
491 | ||
492 | /* | |
493 | * This field stores the size of the data buffer before | |
494 | * compression, and cannot change once set. It is in units | |
495 | * of SPA_MINBLOCKSIZE (e.g. 2 == 1024 bytes) | |
496 | */ | |
497 | uint16_t b_lsize; /* immutable */ | |
498 | uint64_t b_spa; /* immutable */ | |
499 | ||
500 | /* L2ARC fields. Undefined when not in L2ARC. */ | |
501 | l2arc_buf_hdr_t b_l2hdr; | |
502 | /* L1ARC fields. Undefined when in l2arc_only state */ | |
503 | l1arc_buf_hdr_t b_l1hdr; | |
504 | /* | |
505 | * Encryption parameters. Defined only when ARC_FLAG_ENCRYPTED | |
506 | * is set and the L1 header exists. | |
507 | */ | |
508 | arc_buf_hdr_crypt_t b_crypt_hdr; | |
509 | }; | |
510 | ||
511 | typedef struct arc_stats { | |
512 | kstat_named_t arcstat_hits; | |
513 | kstat_named_t arcstat_misses; | |
514 | kstat_named_t arcstat_demand_data_hits; | |
515 | kstat_named_t arcstat_demand_data_misses; | |
516 | kstat_named_t arcstat_demand_metadata_hits; | |
517 | kstat_named_t arcstat_demand_metadata_misses; | |
518 | kstat_named_t arcstat_prefetch_data_hits; | |
519 | kstat_named_t arcstat_prefetch_data_misses; | |
520 | kstat_named_t arcstat_prefetch_metadata_hits; | |
521 | kstat_named_t arcstat_prefetch_metadata_misses; | |
522 | kstat_named_t arcstat_mru_hits; | |
523 | kstat_named_t arcstat_mru_ghost_hits; | |
524 | kstat_named_t arcstat_mfu_hits; | |
525 | kstat_named_t arcstat_mfu_ghost_hits; | |
526 | kstat_named_t arcstat_deleted; | |
527 | /* | |
528 | * Number of buffers that could not be evicted because the hash lock | |
529 | * was held by another thread. The lock may not necessarily be held | |
530 | * by something using the same buffer, since hash locks are shared | |
531 | * by multiple buffers. | |
532 | */ | |
533 | kstat_named_t arcstat_mutex_miss; | |
534 | /* | |
535 | * Number of buffers skipped when updating the access state due to the | |
536 | * header having already been released after acquiring the hash lock. | |
537 | */ | |
538 | kstat_named_t arcstat_access_skip; | |
539 | /* | |
540 | * Number of buffers skipped because they have I/O in progress, are | |
541 | * indirect prefetch buffers that have not lived long enough, or are | |
542 | * not from the spa we're trying to evict from. | |
543 | */ | |
544 | kstat_named_t arcstat_evict_skip; | |
545 | /* | |
546 | * Number of times arc_evict_state() was unable to evict enough | |
547 | * buffers to reach its target amount. | |
548 | */ | |
549 | kstat_named_t arcstat_evict_not_enough; | |
550 | kstat_named_t arcstat_evict_l2_cached; | |
551 | kstat_named_t arcstat_evict_l2_eligible; | |
552 | kstat_named_t arcstat_evict_l2_eligible_mfu; | |
553 | kstat_named_t arcstat_evict_l2_eligible_mru; | |
554 | kstat_named_t arcstat_evict_l2_ineligible; | |
555 | kstat_named_t arcstat_evict_l2_skip; | |
556 | kstat_named_t arcstat_hash_elements; | |
557 | kstat_named_t arcstat_hash_elements_max; | |
558 | kstat_named_t arcstat_hash_collisions; | |
559 | kstat_named_t arcstat_hash_chains; | |
560 | kstat_named_t arcstat_hash_chain_max; | |
561 | kstat_named_t arcstat_p; | |
562 | kstat_named_t arcstat_c; | |
563 | kstat_named_t arcstat_c_min; | |
564 | kstat_named_t arcstat_c_max; | |
565 | /* Not updated directly; only synced in arc_kstat_update. */ | |
566 | kstat_named_t arcstat_size; | |
567 | /* | |
568 | * Number of compressed bytes stored in the arc_buf_hdr_t's b_pabd. | |
569 | * Note that the compressed bytes may match the uncompressed bytes | |
570 | * if the block is either not compressed or compressed arc is disabled. | |
571 | */ | |
572 | kstat_named_t arcstat_compressed_size; | |
573 | /* | |
574 | * Uncompressed size of the data stored in b_pabd. If compressed | |
575 | * arc is disabled then this value will be identical to the stat | |
576 | * above. | |
577 | */ | |
578 | kstat_named_t arcstat_uncompressed_size; | |
579 | /* | |
580 | * Number of bytes stored in all the arc_buf_t's. This is classified | |
581 | * as "overhead" since this data is typically short-lived and will | |
582 | * be evicted from the arc when it becomes unreferenced unless the | |
583 | * zfs_keep_uncompressed_metadata or zfs_keep_uncompressed_level | |
584 | * values have been set (see comment in dbuf.c for more information). | |
585 | */ | |
586 | kstat_named_t arcstat_overhead_size; | |
587 | /* | |
588 | * Number of bytes consumed by internal ARC structures necessary | |
589 | * for tracking purposes; these structures are not actually | |
590 | * backed by ARC buffers. This includes arc_buf_hdr_t structures | |
591 | * (allocated via arc_buf_hdr_t_full and arc_buf_hdr_t_l2only | |
592 | * caches), and arc_buf_t structures (allocated via arc_buf_t | |
593 | * cache). | |
594 | * Not updated directly; only synced in arc_kstat_update. | |
595 | */ | |
596 | kstat_named_t arcstat_hdr_size; | |
597 | /* | |
598 | * Number of bytes consumed by ARC buffers of type equal to | |
599 | * ARC_BUFC_DATA. This is generally consumed by buffers backing | |
600 | * on disk user data (e.g. plain file contents). | |
601 | * Not updated directly; only synced in arc_kstat_update. | |
602 | */ | |
603 | kstat_named_t arcstat_data_size; | |
604 | /* | |
605 | * Number of bytes consumed by ARC buffers of type equal to | |
606 | * ARC_BUFC_METADATA. This is generally consumed by buffers | |
607 | * backing on disk data that is used for internal ZFS | |
608 | * structures (e.g. ZAP, dnode, indirect blocks, etc). | |
609 | * Not updated directly; only synced in arc_kstat_update. | |
610 | */ | |
611 | kstat_named_t arcstat_metadata_size; | |
612 | /* | |
613 | * Number of bytes consumed by dmu_buf_impl_t objects. | |
614 | * Not updated directly; only synced in arc_kstat_update. | |
615 | */ | |
616 | kstat_named_t arcstat_dbuf_size; | |
617 | /* | |
618 | * Number of bytes consumed by dnode_t objects. | |
619 | * Not updated directly; only synced in arc_kstat_update. | |
620 | */ | |
621 | kstat_named_t arcstat_dnode_size; | |
622 | /* | |
623 | * Number of bytes consumed by bonus buffers. | |
624 | * Not updated directly; only synced in arc_kstat_update. | |
625 | */ | |
626 | kstat_named_t arcstat_bonus_size; | |
627 | #if defined(COMPAT_FREEBSD11) | |
628 | /* | |
629 | * Sum of the previous three counters, provided for compatibility. | |
630 | */ | |
631 | kstat_named_t arcstat_other_size; | |
632 | #endif | |
633 | ||
634 | /* | |
635 | * Total number of bytes consumed by ARC buffers residing in the | |
636 | * arc_anon state. This includes *all* buffers in the arc_anon | |
637 | * state; e.g. data, metadata, evictable, and unevictable buffers | |
638 | * are all included in this value. | |
639 | * Not updated directly; only synced in arc_kstat_update. | |
640 | */ | |
641 | kstat_named_t arcstat_anon_size; | |
642 | /* | |
643 | * Number of bytes consumed by ARC buffers that meet the | |
644 | * following criteria: backing buffers of type ARC_BUFC_DATA, | |
645 | * residing in the arc_anon state, and are eligible for eviction | |
646 | * (e.g. have no outstanding holds on the buffer). | |
647 | * Not updated directly; only synced in arc_kstat_update. | |
648 | */ | |
649 | kstat_named_t arcstat_anon_evictable_data; | |
650 | /* | |
651 | * Number of bytes consumed by ARC buffers that meet the | |
652 | * following criteria: backing buffers of type ARC_BUFC_METADATA, | |
653 | * residing in the arc_anon state, and are eligible for eviction | |
654 | * (e.g. have no outstanding holds on the buffer). | |
655 | * Not updated directly; only synced in arc_kstat_update. | |
656 | */ | |
657 | kstat_named_t arcstat_anon_evictable_metadata; | |
658 | /* | |
659 | * Total number of bytes consumed by ARC buffers residing in the | |
660 | * arc_mru state. This includes *all* buffers in the arc_mru | |
661 | * state; e.g. data, metadata, evictable, and unevictable buffers | |
662 | * are all included in this value. | |
663 | * Not updated directly; only synced in arc_kstat_update. | |
664 | */ | |
665 | kstat_named_t arcstat_mru_size; | |
666 | /* | |
667 | * Number of bytes consumed by ARC buffers that meet the | |
668 | * following criteria: backing buffers of type ARC_BUFC_DATA, | |
669 | * residing in the arc_mru state, and are eligible for eviction | |
670 | * (e.g. have no outstanding holds on the buffer). | |
671 | * Not updated directly; only synced in arc_kstat_update. | |
672 | */ | |
673 | kstat_named_t arcstat_mru_evictable_data; | |
674 | /* | |
675 | * Number of bytes consumed by ARC buffers that meet the | |
676 | * following criteria: backing buffers of type ARC_BUFC_METADATA, | |
677 | * residing in the arc_mru state, and are eligible for eviction | |
678 | * (e.g. have no outstanding holds on the buffer). | |
679 | * Not updated directly; only synced in arc_kstat_update. | |
680 | */ | |
681 | kstat_named_t arcstat_mru_evictable_metadata; | |
682 | /* | |
683 | * Total number of bytes that *would have been* consumed by ARC | |
684 | * buffers in the arc_mru_ghost state. The key thing to note | |
685 | * here, is the fact that this size doesn't actually indicate | |
686 | * RAM consumption. The ghost lists only consist of headers and | |
687 | * don't actually have ARC buffers linked off of these headers. | |
688 | * Thus, *if* the headers had associated ARC buffers, these | |
689 | * buffers *would have* consumed this number of bytes. | |
690 | * Not updated directly; only synced in arc_kstat_update. | |
691 | */ | |
692 | kstat_named_t arcstat_mru_ghost_size; | |
693 | /* | |
694 | * Number of bytes that *would have been* consumed by ARC | |
695 | * buffers that are eligible for eviction, of type | |
696 | * ARC_BUFC_DATA, and linked off the arc_mru_ghost state. | |
697 | * Not updated directly; only synced in arc_kstat_update. | |
698 | */ | |
699 | kstat_named_t arcstat_mru_ghost_evictable_data; | |
700 | /* | |
701 | * Number of bytes that *would have been* consumed by ARC | |
702 | * buffers that are eligible for eviction, of type | |
703 | * ARC_BUFC_METADATA, and linked off the arc_mru_ghost state. | |
704 | * Not updated directly; only synced in arc_kstat_update. | |
705 | */ | |
706 | kstat_named_t arcstat_mru_ghost_evictable_metadata; | |
707 | /* | |
708 | * Total number of bytes consumed by ARC buffers residing in the | |
709 | * arc_mfu state. This includes *all* buffers in the arc_mfu | |
710 | * state; e.g. data, metadata, evictable, and unevictable buffers | |
711 | * are all included in this value. | |
712 | * Not updated directly; only synced in arc_kstat_update. | |
713 | */ | |
714 | kstat_named_t arcstat_mfu_size; | |
715 | /* | |
716 | * Number of bytes consumed by ARC buffers that are eligible for | |
717 | * eviction, of type ARC_BUFC_DATA, and reside in the arc_mfu | |
718 | * state. | |
719 | * Not updated directly; only synced in arc_kstat_update. | |
720 | */ | |
721 | kstat_named_t arcstat_mfu_evictable_data; | |
722 | /* | |
723 | * Number of bytes consumed by ARC buffers that are eligible for | |
724 | * eviction, of type ARC_BUFC_METADATA, and reside in the | |
725 | * arc_mfu state. | |
726 | * Not updated directly; only synced in arc_kstat_update. | |
727 | */ | |
728 | kstat_named_t arcstat_mfu_evictable_metadata; | |
729 | /* | |
730 | * Total number of bytes that *would have been* consumed by ARC | |
731 | * buffers in the arc_mfu_ghost state. See the comment above | |
732 | * arcstat_mru_ghost_size for more details. | |
733 | * Not updated directly; only synced in arc_kstat_update. | |
734 | */ | |
735 | kstat_named_t arcstat_mfu_ghost_size; | |
736 | /* | |
737 | * Number of bytes that *would have been* consumed by ARC | |
738 | * buffers that are eligible for eviction, of type | |
739 | * ARC_BUFC_DATA, and linked off the arc_mfu_ghost state. | |
740 | * Not updated directly; only synced in arc_kstat_update. | |
741 | */ | |
742 | kstat_named_t arcstat_mfu_ghost_evictable_data; | |
743 | /* | |
744 | * Number of bytes that *would have been* consumed by ARC | |
745 | * buffers that are eligible for eviction, of type | |
746 | * ARC_BUFC_METADATA, and linked off the arc_mru_ghost state. | |
747 | * Not updated directly; only synced in arc_kstat_update. | |
748 | */ | |
749 | kstat_named_t arcstat_mfu_ghost_evictable_metadata; | |
750 | kstat_named_t arcstat_l2_hits; | |
751 | kstat_named_t arcstat_l2_misses; | |
752 | /* | |
753 | * Allocated size (in bytes) of L2ARC cached buffers by ARC state. | |
754 | */ | |
755 | kstat_named_t arcstat_l2_prefetch_asize; | |
756 | kstat_named_t arcstat_l2_mru_asize; | |
757 | kstat_named_t arcstat_l2_mfu_asize; | |
758 | /* | |
759 | * Allocated size (in bytes) of L2ARC cached buffers by buffer content | |
760 | * type. | |
761 | */ | |
762 | kstat_named_t arcstat_l2_bufc_data_asize; | |
763 | kstat_named_t arcstat_l2_bufc_metadata_asize; | |
764 | kstat_named_t arcstat_l2_feeds; | |
765 | kstat_named_t arcstat_l2_rw_clash; | |
766 | kstat_named_t arcstat_l2_read_bytes; | |
767 | kstat_named_t arcstat_l2_write_bytes; | |
768 | kstat_named_t arcstat_l2_writes_sent; | |
769 | kstat_named_t arcstat_l2_writes_done; | |
770 | kstat_named_t arcstat_l2_writes_error; | |
771 | kstat_named_t arcstat_l2_writes_lock_retry; | |
772 | kstat_named_t arcstat_l2_evict_lock_retry; | |
773 | kstat_named_t arcstat_l2_evict_reading; | |
774 | kstat_named_t arcstat_l2_evict_l1cached; | |
775 | kstat_named_t arcstat_l2_free_on_write; | |
776 | kstat_named_t arcstat_l2_abort_lowmem; | |
777 | kstat_named_t arcstat_l2_cksum_bad; | |
778 | kstat_named_t arcstat_l2_io_error; | |
779 | kstat_named_t arcstat_l2_lsize; | |
780 | kstat_named_t arcstat_l2_psize; | |
781 | /* Not updated directly; only synced in arc_kstat_update. */ | |
782 | kstat_named_t arcstat_l2_hdr_size; | |
783 | /* | |
784 | * Number of L2ARC log blocks written. These are used for restoring the | |
785 | * L2ARC. Updated during writing of L2ARC log blocks. | |
786 | */ | |
787 | kstat_named_t arcstat_l2_log_blk_writes; | |
788 | /* | |
789 | * Moving average of the aligned size of the L2ARC log blocks, in | |
790 | * bytes. Updated during L2ARC rebuild and during writing of L2ARC | |
791 | * log blocks. | |
792 | */ | |
793 | kstat_named_t arcstat_l2_log_blk_avg_asize; | |
794 | /* Aligned size of L2ARC log blocks on L2ARC devices. */ | |
795 | kstat_named_t arcstat_l2_log_blk_asize; | |
796 | /* Number of L2ARC log blocks present on L2ARC devices. */ | |
797 | kstat_named_t arcstat_l2_log_blk_count; | |
798 | /* | |
799 | * Moving average of the aligned size of L2ARC restored data, in bytes, | |
800 | * to the aligned size of their metadata in L2ARC, in bytes. | |
801 | * Updated during L2ARC rebuild and during writing of L2ARC log blocks. | |
802 | */ | |
803 | kstat_named_t arcstat_l2_data_to_meta_ratio; | |
804 | /* | |
805 | * Number of times the L2ARC rebuild was successful for an L2ARC device. | |
806 | */ | |
807 | kstat_named_t arcstat_l2_rebuild_success; | |
808 | /* | |
809 | * Number of times the L2ARC rebuild failed because the device header | |
810 | * was in an unsupported format or corrupted. | |
811 | */ | |
812 | kstat_named_t arcstat_l2_rebuild_abort_unsupported; | |
813 | /* | |
814 | * Number of times the L2ARC rebuild failed because of IO errors | |
815 | * while reading a log block. | |
816 | */ | |
817 | kstat_named_t arcstat_l2_rebuild_abort_io_errors; | |
818 | /* | |
819 | * Number of times the L2ARC rebuild failed because of IO errors when | |
820 | * reading the device header. | |
821 | */ | |
822 | kstat_named_t arcstat_l2_rebuild_abort_dh_errors; | |
823 | /* | |
824 | * Number of L2ARC log blocks which failed to be restored due to | |
825 | * checksum errors. | |
826 | */ | |
827 | kstat_named_t arcstat_l2_rebuild_abort_cksum_lb_errors; | |
828 | /* | |
829 | * Number of times the L2ARC rebuild was aborted due to low system | |
830 | * memory. | |
831 | */ | |
832 | kstat_named_t arcstat_l2_rebuild_abort_lowmem; | |
833 | /* Logical size of L2ARC restored data, in bytes. */ | |
834 | kstat_named_t arcstat_l2_rebuild_size; | |
835 | /* Aligned size of L2ARC restored data, in bytes. */ | |
836 | kstat_named_t arcstat_l2_rebuild_asize; | |
837 | /* | |
838 | * Number of L2ARC log entries (buffers) that were successfully | |
839 | * restored in ARC. | |
840 | */ | |
841 | kstat_named_t arcstat_l2_rebuild_bufs; | |
842 | /* | |
843 | * Number of L2ARC log entries (buffers) already cached in ARC. These | |
844 | * were not restored again. | |
845 | */ | |
846 | kstat_named_t arcstat_l2_rebuild_bufs_precached; | |
847 | /* | |
848 | * Number of L2ARC log blocks that were restored successfully. Each | |
849 | * log block may hold up to L2ARC_LOG_BLK_MAX_ENTRIES buffers. | |
850 | */ | |
851 | kstat_named_t arcstat_l2_rebuild_log_blks; | |
852 | kstat_named_t arcstat_memory_throttle_count; | |
853 | kstat_named_t arcstat_memory_direct_count; | |
854 | kstat_named_t arcstat_memory_indirect_count; | |
855 | kstat_named_t arcstat_memory_all_bytes; | |
856 | kstat_named_t arcstat_memory_free_bytes; | |
857 | kstat_named_t arcstat_memory_available_bytes; | |
858 | kstat_named_t arcstat_no_grow; | |
859 | kstat_named_t arcstat_tempreserve; | |
860 | kstat_named_t arcstat_loaned_bytes; | |
861 | kstat_named_t arcstat_prune; | |
862 | /* Not updated directly; only synced in arc_kstat_update. */ | |
863 | kstat_named_t arcstat_meta_used; | |
864 | kstat_named_t arcstat_meta_limit; | |
865 | kstat_named_t arcstat_dnode_limit; | |
866 | kstat_named_t arcstat_meta_max; | |
867 | kstat_named_t arcstat_meta_min; | |
868 | kstat_named_t arcstat_async_upgrade_sync; | |
869 | kstat_named_t arcstat_demand_hit_predictive_prefetch; | |
870 | kstat_named_t arcstat_demand_hit_prescient_prefetch; | |
871 | kstat_named_t arcstat_need_free; | |
872 | kstat_named_t arcstat_sys_free; | |
873 | kstat_named_t arcstat_raw_size; | |
874 | kstat_named_t arcstat_cached_only_in_progress; | |
875 | kstat_named_t arcstat_abd_chunk_waste_size; | |
876 | } arc_stats_t; | |
877 | ||
878 | typedef struct arc_evict_waiter { | |
879 | list_node_t aew_node; | |
880 | kcondvar_t aew_cv; | |
881 | uint64_t aew_count; | |
882 | } arc_evict_waiter_t; | |
883 | ||
884 | #define ARCSTAT(stat) (arc_stats.stat.value.ui64) | |
885 | ||
886 | #define ARCSTAT_INCR(stat, val) \ | |
887 | atomic_add_64(&arc_stats.stat.value.ui64, (val)) | |
888 | ||
889 | #define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1) | |
890 | #define ARCSTAT_BUMPDOWN(stat) ARCSTAT_INCR(stat, -1) | |
891 | ||
892 | #define arc_no_grow ARCSTAT(arcstat_no_grow) /* do not grow cache size */ | |
893 | #define arc_p ARCSTAT(arcstat_p) /* target size of MRU */ | |
894 | #define arc_c ARCSTAT(arcstat_c) /* target size of cache */ | |
895 | #define arc_c_min ARCSTAT(arcstat_c_min) /* min target cache size */ | |
896 | #define arc_c_max ARCSTAT(arcstat_c_max) /* max target cache size */ | |
897 | #define arc_sys_free ARCSTAT(arcstat_sys_free) /* target system free bytes */ | |
898 | ||
899 | extern taskq_t *arc_prune_taskq; | |
900 | extern arc_stats_t arc_stats; | |
901 | extern hrtime_t arc_growtime; | |
902 | extern boolean_t arc_warm; | |
903 | extern int arc_grow_retry; | |
904 | extern int arc_no_grow_shift; | |
905 | extern int arc_shrink_shift; | |
906 | extern kmutex_t arc_prune_mtx; | |
907 | extern list_t arc_prune_list; | |
908 | extern aggsum_t arc_size; | |
909 | extern arc_state_t *arc_mfu; | |
910 | extern arc_state_t *arc_mru; | |
911 | extern uint_t zfs_arc_pc_percent; | |
912 | extern int arc_lotsfree_percent; | |
913 | extern unsigned long zfs_arc_min; | |
914 | extern unsigned long zfs_arc_max; | |
915 | ||
916 | extern void arc_reduce_target_size(int64_t to_free); | |
917 | extern boolean_t arc_reclaim_needed(void); | |
918 | extern void arc_kmem_reap_soon(void); | |
919 | extern boolean_t arc_is_overflowing(void); | |
920 | extern void arc_wait_for_eviction(uint64_t); | |
921 | ||
922 | extern void arc_lowmem_init(void); | |
923 | extern void arc_lowmem_fini(void); | |
924 | extern void arc_prune_async(int64_t); | |
925 | extern int arc_memory_throttle(spa_t *spa, uint64_t reserve, uint64_t txg); | |
926 | extern uint64_t arc_free_memory(void); | |
927 | extern int64_t arc_available_memory(void); | |
928 | extern void arc_tuning_update(boolean_t); | |
929 | extern void arc_register_hotplug(void); | |
930 | extern void arc_unregister_hotplug(void); | |
931 | ||
932 | extern int param_set_arc_long(ZFS_MODULE_PARAM_ARGS); | |
933 | extern int param_set_arc_int(ZFS_MODULE_PARAM_ARGS); | |
934 | ||
935 | /* used in zdb.c */ | |
936 | boolean_t l2arc_log_blkptr_valid(l2arc_dev_t *dev, | |
937 | const l2arc_log_blkptr_t *lbp); | |
938 | ||
939 | /* used in vdev_trim.c */ | |
940 | void l2arc_dev_hdr_update(l2arc_dev_t *dev); | |
941 | l2arc_dev_t *l2arc_vdev_get(vdev_t *vd); | |
942 | ||
943 | #ifdef __cplusplus | |
944 | } | |
945 | #endif | |
946 | ||
947 | #endif /* _SYS_ARC_IMPL_H */ |