FreeBSD ZFS
The Zettabyte File System
|
00001 /* 00002 * CDDL HEADER START 00003 * 00004 * The contents of this file are subject to the terms of the 00005 * Common Development and Distribution License (the "License"). 00006 * You may not use this file except in compliance with the License. 00007 * 00008 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 00009 * or http://www.opensolaris.org/os/licensing. 00010 * See the License for the specific language governing permissions 00011 * and limitations under the License. 00012 * 00013 * When distributing Covered Code, include this CDDL HEADER in each 00014 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 00015 * If applicable, add the following below this CDDL HEADER, with the 00016 * fields enclosed by brackets "[]" replaced with your own identifying 00017 * information: Portions Copyright [yyyy] [name of copyright owner] 00018 * 00019 * CDDL HEADER END 00020 */ 00021 /* 00022 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 00023 * Copyright (c) 2012 by Delphix. All rights reserved. 00024 */ 00025 00026 #ifndef _SYS_SA_IMPL_H 00027 #define _SYS_SA_IMPL_H 00028 00029 #include <sys/dmu.h> 00030 #include <sys/refcount.h> 00031 #include <sys/list.h> 00032 00037 typedef struct sa_attr_table { 00038 sa_attr_type_t sa_attr; 00039 uint8_t sa_registered; 00040 uint16_t sa_length; 00041 sa_bswap_type_t sa_byteswap; 00042 char *sa_name; 00043 } sa_attr_table_t; 00044 00070 #define ATTR_BSWAP(x) BF32_GET(x, 16, 8) 00071 #define ATTR_LENGTH(x) BF32_GET(x, 24, 16) 00072 #define ATTR_NUM(x) BF32_GET(x, 0, 16) 00073 #define ATTR_ENCODE(x, attr, length, bswap) \ 00074 { \ 00075 BF64_SET(x, 24, 16, length); \ 00076 BF64_SET(x, 16, 8, bswap); \ 00077 BF64_SET(x, 0, 16, attr); \ 00078 } 00079 00080 #define TOC_OFF(x) BF32_GET(x, 0, 23) 00081 #define TOC_ATTR_PRESENT(x) BF32_GET(x, 31, 1) 00082 #define TOC_LEN_IDX(x) BF32_GET(x, 24, 4) 00083 #define TOC_ATTR_ENCODE(x, len_idx, offset) \ 00084 { \ 00085 BF32_SET(x, 31, 1, 1); \ 00086 BF32_SET(x, 24, 7, len_idx); \ 00087 BF32_SET(x, 0, 24, offset); \ 00088 } 00089 00090 #define SA_LAYOUTS "LAYOUTS" 00091 #define SA_REGISTRY "REGISTRY" 00092 00097 typedef struct sa_lot { 00098 avl_node_t lot_num_node; 00099 avl_node_t lot_hash_node; 00100 uint64_t lot_num; 00101 uint64_t lot_hash; 00102 sa_attr_type_t *lot_attrs; 00103 uint32_t lot_var_sizes; 00104 uint32_t lot_attr_count; 00105 list_t lot_idx_tab; 00106 int lot_instance; 00107 } sa_lot_t; 00108 00110 typedef struct sa_idx_tab { 00111 list_node_t sa_next; 00112 sa_lot_t *sa_layout; 00113 uint16_t *sa_variable_lengths; 00114 refcount_t sa_refcount; 00115 uint32_t *sa_idx_tab; 00116 } sa_idx_tab_t; 00117 00137 struct sa_os { 00138 kmutex_t sa_lock; 00139 boolean_t sa_need_attr_registration; 00140 boolean_t sa_force_spill; 00141 uint64_t sa_master_obj; 00142 uint64_t sa_reg_attr_obj; 00143 uint64_t sa_layout_attr_obj; 00144 int sa_num_attrs; 00145 sa_attr_table_t *sa_attr_table; 00146 sa_update_cb_t *sa_update_cb; 00147 avl_tree_t sa_layout_num_tree; 00148 avl_tree_t sa_layout_hash_tree; 00149 int sa_user_table_sz; 00150 sa_attr_type_t *sa_user_table; 00151 }; 00152 00153 #define SA_MAGIC 0x2F505A /* ZFS SA */ 00154 00161 typedef struct sa_hdr_phys { 00162 uint32_t sa_magic; 00182 uint16_t sa_layout_info; 00183 uint16_t sa_lengths[1]; 00184 /* ... Data follows the lengths. */ 00185 } sa_hdr_phys_t; 00186 00187 #define SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10) 00188 #define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 6, 3, 0) 00189 #define SA_HDR_LAYOUT_INFO_ENCODE(x, num, size) \ 00190 { \ 00191 BF32_SET_SB(x, 10, 6, 3, 0, size); \ 00192 BF32_SET(x, 0, 10, num); \ 00193 } 00194 00195 typedef enum sa_buf_type { 00196 SA_BONUS = 1, 00197 SA_SPILL = 2 00198 } sa_buf_type_t; 00199 00200 typedef enum sa_data_op { 00201 SA_LOOKUP, 00202 SA_UPDATE, 00203 SA_ADD, 00204 SA_REPLACE, 00205 SA_REMOVE 00206 } sa_data_op_t; 00207 00213 struct sa_handle { 00214 kmutex_t sa_lock; 00215 dmu_buf_t *sa_bonus; 00216 dmu_buf_t *sa_spill; 00217 objset_t *sa_os; 00218 void *sa_userp; 00219 sa_idx_tab_t *sa_bonus_tab; 00220 sa_idx_tab_t *sa_spill_tab; 00221 }; 00222 00223 #define SA_GET_DB(hdl, type) \ 00224 (dmu_buf_impl_t *)((type == SA_BONUS) ? hdl->sa_bonus : hdl->sa_spill) 00225 00226 #define SA_GET_HDR(hdl, type) \ 00227 ((sa_hdr_phys_t *)((dmu_buf_impl_t *)(SA_GET_DB(hdl, \ 00228 type))->db.db_data)) 00229 00230 #define SA_IDX_TAB_GET(hdl, type) \ 00231 (type == SA_BONUS ? hdl->sa_bonus_tab : hdl->sa_spill_tab) 00232 00233 #define IS_SA_BONUSTYPE(a) \ 00234 ((a == DMU_OT_SA) ? B_TRUE : B_FALSE) 00235 00236 #define SA_BONUSTYPE_FROM_DB(db) \ 00237 (dmu_get_bonustype((dmu_buf_t *)db)) 00238 00239 #define SA_BLKPTR_SPACE (DN_MAX_BONUSLEN - sizeof (blkptr_t)) 00240 00241 #define SA_LAYOUT_NUM(x, type) \ 00242 ((!IS_SA_BONUSTYPE(type) ? 0 : (((IS_SA_BONUSTYPE(type)) && \ 00243 ((SA_HDR_LAYOUT_NUM(x)) == 0)) ? 1 : SA_HDR_LAYOUT_NUM(x)))) 00244 00245 00246 #define SA_REGISTERED_LEN(sa, attr) sa->sa_attr_table[attr].sa_length 00247 00248 #define SA_ATTR_LEN(sa, idx, attr, hdr) ((SA_REGISTERED_LEN(sa, attr) == 0) ?\ 00249 hdr->sa_lengths[TOC_LEN_IDX(idx->sa_idx_tab[attr])] : \ 00250 SA_REGISTERED_LEN(sa, attr)) 00251 00252 #define SA_SET_HDR(hdr, num, size) \ 00253 { \ 00254 hdr->sa_magic = SA_MAGIC; \ 00255 SA_HDR_LAYOUT_INFO_ENCODE(hdr->sa_layout_info, num, size); \ 00256 } 00257 00258 #define SA_ATTR_INFO(sa, idx, hdr, attr, bulk, type, hdl) \ 00259 { \ 00260 bulk.sa_size = SA_ATTR_LEN(sa, idx, attr, hdr); \ 00261 bulk.sa_buftype = type; \ 00262 bulk.sa_addr = \ 00263 (void *)((uintptr_t)TOC_OFF(idx->sa_idx_tab[attr]) + \ 00264 (uintptr_t)hdr); \ 00265 } 00266 00267 #define SA_HDR_SIZE_MATCH_LAYOUT(hdr, tb) \ 00268 (SA_HDR_SIZE(hdr) == (sizeof (sa_hdr_phys_t) + \ 00269 (tb->lot_var_sizes > 1 ? P2ROUNDUP((tb->lot_var_sizes - 1) * \ 00270 sizeof (uint16_t), 8) : 0))) 00271 00272 int sa_add_impl(sa_handle_t *, sa_attr_type_t, 00273 uint32_t, sa_data_locator_t, void *, dmu_tx_t *); 00274 00275 void sa_register_update_callback_locked(objset_t *, sa_update_cb_t *); 00276 int sa_size_locked(sa_handle_t *, sa_attr_type_t, int *); 00277 00278 void sa_default_locator(void **, uint32_t *, uint32_t, boolean_t, void *); 00279 int sa_attr_size(sa_os_t *, sa_idx_tab_t *, sa_attr_type_t, 00280 uint16_t *, sa_hdr_phys_t *); 00281 00282 #ifdef __cplusplus 00283 extern "C" { 00284 #endif 00285 00286 #ifdef __cplusplus 00287 } 00288 #endif 00289 00290 #endif /* _SYS_SA_IMPL_H */