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) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 00023 * Copyright (c) 2012 by Delphix. All rights reserved. 00024 */ 00025 00026 #ifndef _SYS_DNODE_H 00027 #define _SYS_DNODE_H 00028 00029 #include <sys/zfs_context.h> 00030 #include <sys/avl.h> 00031 #include <sys/spa.h> 00032 #include <sys/txg.h> 00033 #include <sys/zio.h> 00034 #include <sys/refcount.h> 00035 #include <sys/dmu_zfetch.h> 00036 #include <sys/zrlock.h> 00037 00038 #ifdef __cplusplus 00039 extern "C" { 00040 #endif 00041 00046 #define DNODE_MUST_BE_ALLOCATED 1 00047 #define DNODE_MUST_BE_FREE 2 00048 00054 #define DNODE_FIND_HOLE 1 00055 #define DNODE_FIND_BACKWARDS 2 00056 #define DNODE_FIND_HAVELOCK 4 00057 00063 #define DNODE_SHIFT 9 00064 #define DN_MIN_INDBLKSHIFT 10 00065 #define DN_MAX_INDBLKSHIFT 14 00066 #define DNODE_BLOCK_SHIFT 14 00067 #define DNODE_CORE_SIZE 64 00068 #define DN_MAX_OBJECT_SHIFT 48 00069 #define DN_MAX_OFFSET_SHIFT 64 00080 #define DN_ID_CHKED_BONUS 0x1 00081 #define DN_ID_CHKED_SPILL 0x2 00082 #define DN_ID_OLD_EXIST 0x4 00083 #define DN_ID_NEW_EXIST 0x8 00084 00090 #define DNODE_SIZE (1 << DNODE_SHIFT) 00091 #define DN_MAX_NBLKPTR ((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT) 00092 #define DN_MAX_BONUSLEN (DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT)) 00093 #define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT) 00094 #define DN_ZERO_BONUSLEN (DN_MAX_BONUSLEN + 1) 00095 #define DN_KILL_SPILLBLK (1) 00096 00097 #define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT) 00098 #define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT) 00099 #define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT) 00100 #define DNODES_PER_LEVEL (1ULL << DNODES_PER_LEVEL_SHIFT) 00101 00103 /* The +2 here is a cheesy way to round up */ 00104 #define DN_MAX_LEVELS (2 + ((DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT) / \ 00105 (DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT))) 00106 00107 #define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \ 00108 (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t)))) 00109 00110 #define DN_USED_BYTES(dnp) (((dnp)->dn_flags & DNODE_FLAG_USED_BYTES) ? \ 00111 (dnp)->dn_used : (dnp)->dn_used << SPA_MINBLOCKSHIFT) 00112 00113 #define EPB(blkshift, typeshift) (1 << (blkshift - typeshift)) 00114 00115 struct dmu_buf_impl; 00116 struct objset; 00117 struct zio; 00118 00119 enum dnode_dirtycontext { 00120 DN_UNDIRTIED, 00121 DN_DIRTY_OPEN, 00122 DN_DIRTY_SYNC 00123 }; 00124 00126 #define DNODE_FLAG_USED_BYTES (1<<0) 00127 #define DNODE_FLAG_USERUSED_ACCOUNTED (1<<1) 00128 00130 #define DNODE_FLAG_SPILL_BLKPTR (1<<2) 00131 00132 typedef struct dnode_phys { 00133 uint8_t dn_type; 00134 uint8_t dn_indblkshift; 00135 uint8_t dn_nlevels; 00136 uint8_t dn_nblkptr; 00137 uint8_t dn_bonustype; 00138 uint8_t dn_checksum; 00139 uint8_t dn_compress; 00140 uint8_t dn_flags; 00141 uint16_t dn_datablkszsec; 00142 uint16_t dn_bonuslen; 00143 uint8_t dn_pad2[4]; 00144 00145 /* accounting is protected by dn_dirty_mtx */ 00146 uint64_t dn_maxblkid; 00147 uint64_t dn_used; 00149 uint64_t dn_pad3[4]; 00150 00151 blkptr_t dn_blkptr[1]; 00152 uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)]; 00153 blkptr_t dn_spill; 00154 } dnode_phys_t; 00155 00156 typedef struct dnode { 00161 krwlock_t dn_struct_rwlock; 00162 00164 list_node_t dn_link; 00165 00169 struct objset *dn_objset; 00170 uint64_t dn_object; 00171 struct dmu_buf_impl *dn_dbuf; 00172 struct dnode_handle *dn_handle; 00173 dnode_phys_t *dn_phys; 00183 dmu_object_type_t dn_type; 00184 uint16_t dn_bonuslen; 00185 uint8_t dn_bonustype; 00186 uint8_t dn_nblkptr; 00187 uint8_t dn_checksum; 00188 uint8_t dn_compress; 00189 uint8_t dn_nlevels; 00190 uint8_t dn_indblkshift; 00191 uint8_t dn_datablkshift; 00192 uint8_t dn_moved; 00193 uint16_t dn_datablkszsec; 00194 uint32_t dn_datablksz; 00195 uint64_t dn_maxblkid; 00196 uint8_t dn_next_nblkptr[TXG_SIZE]; 00197 uint8_t dn_next_nlevels[TXG_SIZE]; 00198 uint8_t dn_next_indblkshift[TXG_SIZE]; 00199 uint8_t dn_next_bonustype[TXG_SIZE]; 00200 uint8_t dn_rm_spillblk[TXG_SIZE]; 00201 uint16_t dn_next_bonuslen[TXG_SIZE]; 00202 uint32_t dn_next_blksz[TXG_SIZE]; 00209 uint32_t dn_dbufs_count; 00215 list_node_t dn_dirty_link[TXG_SIZE]; 00221 kmutex_t dn_mtx; 00222 list_t dn_dirty_records[TXG_SIZE]; 00223 avl_tree_t dn_ranges[TXG_SIZE]; 00224 uint64_t dn_allocated_txg; 00225 uint64_t dn_free_txg; 00226 uint64_t dn_assigned_txg; 00227 kcondvar_t dn_notxholds; 00228 enum dnode_dirtycontext dn_dirtyctx; 00229 uint8_t *dn_dirtyctx_firstset; 00235 refcount_t dn_tx_holds; 00236 refcount_t dn_holds; 00239 kmutex_t dn_dbufs_mtx; 00240 list_t dn_dbufs; 00245 struct dmu_buf_impl *dn_bonus; 00248 boolean_t dn_have_spill; 00253 zio_t *dn_zio; 00259 uint64_t dn_oldused; 00260 uint64_t dn_oldflags; 00261 uint64_t dn_olduid, dn_oldgid; 00262 uint64_t dn_newuid, dn_newgid; 00263 int dn_id_flags; 00267 struct zfetch dn_zfetch; 00268 } dnode_t; 00269 00275 typedef struct dnode_handle { 00277 zrlock_t dnh_zrlock; 00278 dnode_t *dnh_dnode; 00279 } dnode_handle_t; 00280 00281 typedef struct dnode_children { 00282 size_t dnc_count; 00283 dnode_handle_t dnc_children[1]; 00284 } dnode_children_t; 00285 00286 typedef struct free_range { 00287 avl_node_t fr_node; 00288 uint64_t fr_blkid; 00289 uint64_t fr_nblks; 00290 } free_range_t; 00291 00292 dnode_t *dnode_special_open(struct objset *dd, dnode_phys_t *dnp, 00293 uint64_t object, dnode_handle_t *dnh); 00294 void dnode_special_close(dnode_handle_t *dnh); 00295 00296 void dnode_setbonuslen(dnode_t *dn, int newsize, dmu_tx_t *tx); 00297 void dnode_setbonus_type(dnode_t *dn, dmu_object_type_t, dmu_tx_t *tx); 00298 void dnode_rm_spill(dnode_t *dn, dmu_tx_t *tx); 00299 00300 int dnode_hold(struct objset *dd, uint64_t object, 00301 void *ref, dnode_t **dnp); 00302 int dnode_hold_impl(struct objset *dd, uint64_t object, int flag, 00303 void *ref, dnode_t **dnp); 00304 boolean_t dnode_add_ref(dnode_t *dn, void *ref); 00305 void dnode_rele(dnode_t *dn, void *ref); 00306 void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx); 00307 void dnode_sync(dnode_t *dn, dmu_tx_t *tx); 00308 void dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs, 00309 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx); 00310 void dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, 00311 dmu_object_type_t bonustype, int bonuslen, dmu_tx_t *tx); 00312 void dnode_free(dnode_t *dn, dmu_tx_t *tx); 00313 void dnode_byteswap(dnode_phys_t *dnp); 00314 void dnode_buf_byteswap(void *buf, size_t size); 00315 void dnode_verify(dnode_t *dn); 00316 int dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx); 00317 void dnode_free_range(dnode_t *dn, uint64_t off, uint64_t len, dmu_tx_t *tx); 00318 void dnode_clear_range(dnode_t *dn, uint64_t blkid, 00319 uint64_t nblks, dmu_tx_t *tx); 00320 void dnode_diduse_space(dnode_t *dn, int64_t space); 00321 void dnode_willuse_space(dnode_t *dn, int64_t space, dmu_tx_t *tx); 00322 void dnode_new_blkid(dnode_t *dn, uint64_t blkid, dmu_tx_t *tx, boolean_t); 00323 uint64_t dnode_block_freed(dnode_t *dn, uint64_t blkid); 00324 void dnode_init(void); 00325 void dnode_fini(void); 00326 int dnode_next_offset(dnode_t *dn, int flags, uint64_t *off, 00327 int minlvl, uint64_t blkfill, uint64_t txg); 00328 void dnode_evict_dbufs(dnode_t *dn); 00329 00330 #ifdef ZFS_DEBUG 00331 00332 /* 00333 * There should be a ## between the string literal and fmt, to make it 00334 * clear that we're joining two strings together, but that piece of shit 00335 * gcc doesn't support that preprocessor token. 00336 */ 00337 #define dprintf_dnode(dn, fmt, ...) do { \ 00338 if (zfs_flags & ZFS_DEBUG_DPRINTF) { \ 00339 char __db_buf[32]; \ 00340 uint64_t __db_obj = (dn)->dn_object; \ 00341 if (__db_obj == DMU_META_DNODE_OBJECT) \ 00342 (void) strcpy(__db_buf, "mdn"); \ 00343 else \ 00344 (void) snprintf(__db_buf, sizeof (__db_buf), "%lld", \ 00345 (u_longlong_t)__db_obj);\ 00346 dprintf_ds((dn)->dn_objset->os_dsl_dataset, "obj=%s " fmt, \ 00347 __db_buf, __VA_ARGS__); \ 00348 } \ 00349 _NOTE(CONSTCOND) } while (0) 00350 00351 #define DNODE_VERIFY(dn) dnode_verify(dn) 00352 #define FREE_VERIFY(db, start, end, tx) free_verify(db, start, end, tx) 00353 00354 #else 00355 00356 #define dprintf_dnode(db, fmt, ...) 00357 #define DNODE_VERIFY(dn) 00358 #define FREE_VERIFY(db, start, end, tx) 00359 00360 #endif 00361 00362 #ifdef __cplusplus 00363 } 00364 #endif 00365 00366 #endif /* _SYS_DNODE_H */