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 */ 00024 00025 #ifndef _SYS_DBUF_H 00026 #define _SYS_DBUF_H 00027 00028 #include <sys/dmu.h> 00029 #include <sys/spa.h> 00030 #include <sys/txg.h> 00031 #include <sys/zio.h> 00032 #include <sys/arc.h> 00033 #include <sys/zfs_context.h> 00034 #include <sys/refcount.h> 00035 #include <sys/zrlock.h> 00036 00037 #ifdef __cplusplus 00038 extern "C" { 00039 #endif 00040 00041 #define IN_DMU_SYNC 2 00042 00048 #define DB_RF_MUST_SUCCEED (1 << 0) 00049 #define DB_RF_CANFAIL (1 << 1) 00050 #define DB_RF_HAVESTRUCT (1 << 2) 00051 #define DB_RF_NOPREFETCH (1 << 3) 00052 #define DB_RF_NEVERWAIT (1 << 4) 00053 #define DB_RF_CACHED (1 << 5) 00054 00072 typedef enum dbuf_states { 00073 DB_UNCACHED, 00074 DB_FILL, 00075 DB_NOFILL, 00076 DB_READ, 00077 DB_CACHED, 00078 DB_EVICTING 00079 } dbuf_states_t; 00080 00081 struct dnode; 00082 struct dmu_tx; 00083 00084 /* 00085 * level = 0 means the user data 00086 * level = 1 means the single indirect block 00087 * etc. 00088 */ 00089 00090 struct dmu_buf_impl; 00091 00092 typedef enum override_states { 00093 DR_NOT_OVERRIDDEN, 00094 DR_IN_DMU_SYNC, 00095 DR_OVERRIDDEN 00096 } override_states_t; 00097 00106 typedef struct dbuf_dirty_record { 00108 list_node_t dr_dirty_node; 00109 00111 uint64_t dr_txg; 00112 00114 zio_t *dr_zio; 00115 00117 struct dmu_buf_impl *dr_dbuf; 00118 00120 struct dbuf_dirty_record *dr_next; 00121 00123 struct dbuf_dirty_record *dr_parent; 00124 00125 union dirty_types { 00126 struct dirty_indirect { 00127 00129 kmutex_t dr_mtx; 00130 00132 list_t dr_children; 00133 } di; 00134 struct dirty_leaf { 00135 00141 arc_buf_t *dr_data; 00142 blkptr_t dr_overridden_by; 00143 override_states_t dr_override_state; 00144 uint8_t dr_copies; 00145 } dl; 00146 } dt; 00147 } dbuf_dirty_record_t; 00148 00149 typedef struct dmu_buf_impl { 00150 /* 00151 * The following members are immutable, with the exception of 00152 * db.db_data, which is protected by db_mtx. 00153 */ 00154 00156 dmu_buf_t db; 00157 00159 struct objset *db_objset; 00160 00164 struct dnode_handle *db_dnode_handle; 00165 00174 struct dmu_buf_impl *db_parent; 00175 00179 struct dmu_buf_impl *db_hash_next; 00180 00182 uint64_t db_blkid; 00183 00188 blkptr_t *db_blkptr; 00189 00196 uint8_t db_level; 00197 00199 kmutex_t db_mtx; 00200 00204 dbuf_states_t db_state; 00205 00211 refcount_t db_holds; 00212 00214 arc_buf_t *db_buf; 00215 00216 kcondvar_t db_changed; 00217 dbuf_dirty_record_t *db_data_pending; 00218 00220 dbuf_dirty_record_t *db_last_dirty; 00221 00226 list_node_t db_link; 00227 00231 void *db_user_ptr; 00232 void **db_user_data_ptr_ptr; 00233 dmu_buf_evict_func_t *db_evict_func; 00234 00235 uint8_t db_immediate_evict; 00236 uint8_t db_freed_in_flight; 00237 00238 uint8_t db_dirtycnt; 00239 } dmu_buf_impl_t; 00240 00241 #define DBUF_MUTEXES 256 00242 #define DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)]) 00243 00244 typedef struct dbuf_hash_table { 00245 uint64_t hash_table_mask; 00246 dmu_buf_impl_t **hash_table; 00247 kmutex_t hash_mutexes[DBUF_MUTEXES]; 00248 } dbuf_hash_table_t; 00249 00250 00251 uint64_t dbuf_whichblock(struct dnode *di, uint64_t offset); 00252 00253 dmu_buf_impl_t *dbuf_create_tlib(struct dnode *dn, char *data); 00254 void dbuf_create_bonus(struct dnode *dn); 00255 int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx); 00256 void dbuf_spill_hold(struct dnode *dn, dmu_buf_impl_t **dbp, void *tag); 00257 00258 void dbuf_rm_spill(struct dnode *dn, dmu_tx_t *tx); 00259 00260 dmu_buf_impl_t *dbuf_hold(struct dnode *dn, uint64_t blkid, void *tag); 00261 dmu_buf_impl_t *dbuf_hold_level(struct dnode *dn, int level, uint64_t blkid, 00262 void *tag); 00263 int dbuf_hold_impl(struct dnode *dn, uint8_t level, uint64_t blkid, int create, 00264 void *tag, dmu_buf_impl_t **dbp); 00265 00266 void dbuf_prefetch(struct dnode *dn, uint64_t blkid); 00267 00268 void dbuf_add_ref(dmu_buf_impl_t *db, void *tag); 00269 uint64_t dbuf_refcount(dmu_buf_impl_t *db); 00270 00271 void dbuf_rele(dmu_buf_impl_t *db, void *tag); 00272 void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag); 00273 00274 dmu_buf_impl_t *dbuf_find(struct dnode *dn, uint8_t level, uint64_t blkid); 00275 00276 int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags); 00277 void dbuf_will_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx); 00278 void dbuf_fill_done(dmu_buf_impl_t *db, dmu_tx_t *tx); 00279 void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx); 00280 void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx); 00281 void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx); 00282 void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx); 00283 dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx); 00284 arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db); 00285 00286 void dbuf_clear(dmu_buf_impl_t *db); 00287 void dbuf_evict(dmu_buf_impl_t *db); 00288 00289 void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx); 00290 void dbuf_unoverride(dbuf_dirty_record_t *dr); 00291 void dbuf_sync_list(list_t *list, dmu_tx_t *tx); 00292 void dbuf_release_bp(dmu_buf_impl_t *db); 00293 00294 void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end, 00295 struct dmu_tx *); 00296 00297 void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx); 00298 00299 #define DB_DNODE(_db) ((_db)->db_dnode_handle->dnh_dnode) 00300 #define DB_DNODE_LOCK(_db) ((_db)->db_dnode_handle->dnh_zrlock) 00301 #define DB_DNODE_ENTER(_db) (zrl_add(&DB_DNODE_LOCK(_db))) 00302 #define DB_DNODE_EXIT(_db) (zrl_remove(&DB_DNODE_LOCK(_db))) 00303 #define DB_DNODE_HELD(_db) (!zrl_is_zero(&DB_DNODE_LOCK(_db))) 00304 #define DB_GET_SPA(_spa_p, _db) { \ 00305 dnode_t *__dn; \ 00306 DB_DNODE_ENTER(_db); \ 00307 __dn = DB_DNODE(_db); \ 00308 *(_spa_p) = __dn->dn_objset->os_spa; \ 00309 DB_DNODE_EXIT(_db); \ 00310 } 00311 #define DB_GET_OBJSET(_os_p, _db) { \ 00312 dnode_t *__dn; \ 00313 DB_DNODE_ENTER(_db); \ 00314 __dn = DB_DNODE(_db); \ 00315 *(_os_p) = __dn->dn_objset; \ 00316 DB_DNODE_EXIT(_db); \ 00317 } 00318 00319 void dbuf_init(void); 00320 void dbuf_fini(void); 00321 00322 boolean_t dbuf_is_metadata(dmu_buf_impl_t *db); 00323 00324 #define DBUF_IS_METADATA(_db) \ 00325 (dbuf_is_metadata(_db)) 00326 00327 #define DBUF_GET_BUFC_TYPE(_db) \ 00328 (DBUF_IS_METADATA(_db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA) 00329 00330 #define DBUF_IS_CACHEABLE(_db) \ 00331 ((_db)->db_objset->os_primary_cache == ZFS_CACHE_ALL || \ 00332 (DBUF_IS_METADATA(_db) && \ 00333 ((_db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA))) 00334 00335 #define DBUF_IS_L2CACHEABLE(_db) \ 00336 ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL || \ 00337 (DBUF_IS_METADATA(_db) && \ 00338 ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA))) 00339 00340 #ifdef ZFS_DEBUG 00341 00342 /* 00343 * There should be a ## between the string literal and fmt, to make it 00344 * clear that we're joining two strings together, but gcc does not 00345 * support that preprocessor token. 00346 */ 00347 #define dprintf_dbuf(dbuf, fmt, ...) do { \ 00348 if (zfs_flags & ZFS_DEBUG_DPRINTF) { \ 00349 char __db_buf[32]; \ 00350 uint64_t __db_obj = (dbuf)->db.db_object; \ 00351 if (__db_obj == DMU_META_DNODE_OBJECT) \ 00352 (void) strcpy(__db_buf, "mdn"); \ 00353 else \ 00354 (void) snprintf(__db_buf, sizeof (__db_buf), "%lld", \ 00355 (u_longlong_t)__db_obj); \ 00356 dprintf_ds((dbuf)->db_objset->os_dsl_dataset, \ 00357 "obj=%s lvl=%u blkid=%lld " fmt, \ 00358 __db_buf, (dbuf)->db_level, \ 00359 (u_longlong_t)(dbuf)->db_blkid, __VA_ARGS__); \ 00360 } \ 00361 _NOTE(CONSTCOND) } while (0) 00362 00363 #define dprintf_dbuf_bp(db, bp, fmt, ...) do { \ 00364 if (zfs_flags & ZFS_DEBUG_DPRINTF) { \ 00365 char *__blkbuf = kmem_alloc(BP_SPRINTF_LEN, KM_SLEEP); \ 00366 sprintf_blkptr(__blkbuf, bp); \ 00367 dprintf_dbuf(db, fmt " %s\n", __VA_ARGS__, __blkbuf); \ 00368 kmem_free(__blkbuf, BP_SPRINTF_LEN); \ 00369 } \ 00370 _NOTE(CONSTCOND) } while (0) 00371 00372 #define DBUF_VERIFY(db) dbuf_verify(db) 00373 00374 #else 00375 00376 #define dprintf_dbuf(db, fmt, ...) 00377 #define dprintf_dbuf_bp(db, bp, fmt, ...) 00378 #define DBUF_VERIFY(db) 00379 00380 #endif 00381 00382 00383 #ifdef __cplusplus 00384 } 00385 #endif 00386 00387 #endif /* _SYS_DBUF_H */