FreeBSD ZFS
The Zettabyte File System

sys/sa_impl.h

Go to the documentation of this file.
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 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines