1fa9e4066Sahrens /* 2fa9e4066Sahrens * CDDL HEADER START 3fa9e4066Sahrens * 4fa9e4066Sahrens * The contents of this file are subject to the terms of the 5ea8dc4b6Seschrock * Common Development and Distribution License (the "License"). 6ea8dc4b6Seschrock * You may not use this file except in compliance with the License. 7fa9e4066Sahrens * 8fa9e4066Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e4066Sahrens * or http://www.opensolaris.org/os/licensing. 10fa9e4066Sahrens * See the License for the specific language governing permissions 11fa9e4066Sahrens * and limitations under the License. 12fa9e4066Sahrens * 13fa9e4066Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e4066Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e4066Sahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e4066Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e4066Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e4066Sahrens * 19fa9e4066Sahrens * CDDL HEADER END 20fa9e4066Sahrens */ 21fa9e4066Sahrens /* 223f9d6ad7SLin Ling * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23c2919acbSMatthew Ahrens * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 24aad02571SSaso Kiselkov * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. 25bc9014e6SJustin Gibbs * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. 26fa9e4066Sahrens */ 27fa9e4066Sahrens 28fa9e4066Sahrens #ifndef _SYS_DBUF_H 29fa9e4066Sahrens #define _SYS_DBUF_H 30fa9e4066Sahrens 31fa9e4066Sahrens #include <sys/dmu.h> 32fa9e4066Sahrens #include <sys/spa.h> 33fa9e4066Sahrens #include <sys/txg.h> 34fa9e4066Sahrens #include <sys/zio.h> 35fa9e4066Sahrens #include <sys/arc.h> 36fa9e4066Sahrens #include <sys/zfs_context.h> 37fa9e4066Sahrens #include <sys/refcount.h> 38744947dcSTom Erickson #include <sys/zrlock.h> 39dcbf3bd6SGeorge Wilson #include <sys/multilist.h> 40fa9e4066Sahrens 41fa9e4066Sahrens #ifdef __cplusplus 42fa9e4066Sahrens extern "C" { 43fa9e4066Sahrens #endif 44fa9e4066Sahrens 45c717a561Smaybee #define IN_DMU_SYNC 2 46fa9e4066Sahrens 47fa9e4066Sahrens /* 48ea8dc4b6Seschrock * define flags for dbuf_read 49fa9e4066Sahrens */ 50fa9e4066Sahrens 5113506d1eSmaybee #define DB_RF_MUST_SUCCEED (1 << 0) 52fa9e4066Sahrens #define DB_RF_CANFAIL (1 << 1) 53fa9e4066Sahrens #define DB_RF_HAVESTRUCT (1 << 2) 54fa9e4066Sahrens #define DB_RF_NOPREFETCH (1 << 3) 55ea8dc4b6Seschrock #define DB_RF_NEVERWAIT (1 << 4) 5613506d1eSmaybee #define DB_RF_CACHED (1 << 5) 57eb633035STom Caputi #define DB_RF_NO_DECRYPT (1 << 6) 58fa9e4066Sahrens 59fa9e4066Sahrens /* 6082c9918fSTim Haley * The simplified state transition diagram for dbufs looks like: 61fa9e4066Sahrens * 62fa9e4066Sahrens * +----> READ ----+ 63fa9e4066Sahrens * | | 64fa9e4066Sahrens * | V 65ea8dc4b6Seschrock * (alloc)-->UNCACHED CACHED-->EVICTING-->(free) 6682c9918fSTim Haley * | ^ ^ 6782c9918fSTim Haley * | | | 6882c9918fSTim Haley * +----> FILL ----+ | 6982c9918fSTim Haley * | | 7082c9918fSTim Haley * | | 7182c9918fSTim Haley * +--------> NOFILL -------+ 7286bb58aeSAlex Reece * 7386bb58aeSAlex Reece * DB_SEARCH is an invalid state for a dbuf. It is used by dbuf_free_range 7486bb58aeSAlex Reece * to find all dbufs in a range of a dnode and must be less than any other 7586bb58aeSAlex Reece * dbuf_states_t (see comment on dn_dbufs in dnode.h). 76fa9e4066Sahrens */ 77fa9e4066Sahrens typedef enum dbuf_states { 7886bb58aeSAlex Reece DB_SEARCH = -1, 79fa9e4066Sahrens DB_UNCACHED, 80fa9e4066Sahrens DB_FILL, 8182c9918fSTim Haley DB_NOFILL, 82fa9e4066Sahrens DB_READ, 83ea8dc4b6Seschrock DB_CACHED, 84ea8dc4b6Seschrock DB_EVICTING 85fa9e4066Sahrens } dbuf_states_t; 86fa9e4066Sahrens 87adb52d92SMatthew Ahrens typedef enum dbuf_cached_state { 88adb52d92SMatthew Ahrens DB_NO_CACHE = -1, 89adb52d92SMatthew Ahrens DB_DBUF_CACHE, 90adb52d92SMatthew Ahrens DB_DBUF_METADATA_CACHE, 91adb52d92SMatthew Ahrens DB_CACHE_MAX 92adb52d92SMatthew Ahrens } dbuf_cached_state_t; 93adb52d92SMatthew Ahrens 94fa9e4066Sahrens struct dnode; 95fa9e4066Sahrens struct dmu_tx; 96fa9e4066Sahrens 97fa9e4066Sahrens /* 98fa9e4066Sahrens * level = 0 means the user data 99fa9e4066Sahrens * level = 1 means the single indirect block 100fa9e4066Sahrens * etc. 101fa9e4066Sahrens */ 102fa9e4066Sahrens 103c717a561Smaybee struct dmu_buf_impl; 104c717a561Smaybee 105c717a561Smaybee typedef enum override_states { 106c717a561Smaybee DR_NOT_OVERRIDDEN, 107c717a561Smaybee DR_IN_DMU_SYNC, 108c717a561Smaybee DR_OVERRIDDEN 109c717a561Smaybee } override_states_t; 110c717a561Smaybee 1119704bf7fSPaul Dagnelie typedef enum db_lock_type { 1129704bf7fSPaul Dagnelie DLT_NONE, 1139704bf7fSPaul Dagnelie DLT_PARENT, 1149704bf7fSPaul Dagnelie DLT_OBJSET 1159704bf7fSPaul Dagnelie } db_lock_type_t; 1169704bf7fSPaul Dagnelie 117c717a561Smaybee typedef struct dbuf_dirty_record { 118c717a561Smaybee /* link on our parents dirty list */ 119c717a561Smaybee list_node_t dr_dirty_node; 120c717a561Smaybee 121c717a561Smaybee /* transaction group this data will sync in */ 122c717a561Smaybee uint64_t dr_txg; 123c717a561Smaybee 124c717a561Smaybee /* zio of outstanding write IO */ 125c717a561Smaybee zio_t *dr_zio; 126c717a561Smaybee 127c717a561Smaybee /* pointer back to our dbuf */ 128c717a561Smaybee struct dmu_buf_impl *dr_dbuf; 129c717a561Smaybee 130c717a561Smaybee /* pointer to next dirty record */ 131c717a561Smaybee struct dbuf_dirty_record *dr_next; 132c717a561Smaybee 133c717a561Smaybee /* pointer to parent dirty record */ 134c717a561Smaybee struct dbuf_dirty_record *dr_parent; 135c717a561Smaybee 13669962b56SMatthew Ahrens /* How much space was changed to dsl_pool_dirty_space() for this? */ 13769962b56SMatthew Ahrens unsigned int dr_accounted; 13869962b56SMatthew Ahrens 13911ceac77SAlex Reece /* A copy of the bp that points to us */ 14011ceac77SAlex Reece blkptr_t dr_bp_copy; 14111ceac77SAlex Reece 142c717a561Smaybee union dirty_types { 143c717a561Smaybee struct dirty_indirect { 144c717a561Smaybee 145c717a561Smaybee /* protect access to list */ 146c717a561Smaybee kmutex_t dr_mtx; 147c717a561Smaybee 148c717a561Smaybee /* Our list of dirty children */ 149c717a561Smaybee list_t dr_children; 150c717a561Smaybee } di; 151c717a561Smaybee struct dirty_leaf { 152c717a561Smaybee 153c717a561Smaybee /* 154c717a561Smaybee * dr_data is set when we dirty the buffer 155c717a561Smaybee * so that we can retain the pointer even if it 156c717a561Smaybee * gets COW'd in a subsequent transaction group. 157c717a561Smaybee */ 158c717a561Smaybee arc_buf_t *dr_data; 159c717a561Smaybee blkptr_t dr_overridden_by; 160c717a561Smaybee override_states_t dr_override_state; 161b24ab676SJeff Bonwick uint8_t dr_copies; 16280901aeaSGeorge Wilson boolean_t dr_nopwrite; 163eb633035STom Caputi boolean_t dr_has_raw_params; 164eb633035STom Caputi 165eb633035STom Caputi /* 166eb633035STom Caputi * If dr_has_raw_params is set, the following crypt 167eb633035STom Caputi * params will be set on the BP that's written. 168eb633035STom Caputi */ 169eb633035STom Caputi boolean_t dr_byteorder; 170eb633035STom Caputi uint8_t dr_salt[ZIO_DATA_SALT_LEN]; 171eb633035STom Caputi uint8_t dr_iv[ZIO_DATA_IV_LEN]; 172eb633035STom Caputi uint8_t dr_mac[ZIO_DATA_MAC_LEN]; 173c717a561Smaybee } dl; 174c717a561Smaybee } dt; 175c717a561Smaybee } dbuf_dirty_record_t; 176c717a561Smaybee 177fa9e4066Sahrens typedef struct dmu_buf_impl { 178fa9e4066Sahrens /* 179fa9e4066Sahrens * The following members are immutable, with the exception of 180fa9e4066Sahrens * db.db_data, which is protected by db_mtx. 181fa9e4066Sahrens */ 182fa9e4066Sahrens 183fa9e4066Sahrens /* the publicly visible structure */ 184fa9e4066Sahrens dmu_buf_t db; 185fa9e4066Sahrens 186fa9e4066Sahrens /* the objset we belong to */ 187503ad85cSMatthew Ahrens struct objset *db_objset; 188fa9e4066Sahrens 189fa9e4066Sahrens /* 190744947dcSTom Erickson * handle to safely access the dnode we belong to (NULL when evicted) 191fa9e4066Sahrens */ 192744947dcSTom Erickson struct dnode_handle *db_dnode_handle; 193fa9e4066Sahrens 194fa9e4066Sahrens /* 195fa9e4066Sahrens * our parent buffer; if the dnode points to us directly, 196744947dcSTom Erickson * db_parent == db_dnode_handle->dnh_dnode->dn_dbuf 197fa9e4066Sahrens * only accessed by sync thread ??? 198fa9e4066Sahrens * (NULL when evicted) 199744947dcSTom Erickson * May change from NULL to non-NULL under the protection of db_mtx 200744947dcSTom Erickson * (see dbuf_check_blkptr()) 201fa9e4066Sahrens */ 202fa9e4066Sahrens struct dmu_buf_impl *db_parent; 203fa9e4066Sahrens 204fa9e4066Sahrens /* 205fa9e4066Sahrens * link for hash table of all dmu_buf_impl_t's 206fa9e4066Sahrens */ 207fa9e4066Sahrens struct dmu_buf_impl *db_hash_next; 208fa9e4066Sahrens 209fa9e4066Sahrens /* our block number */ 210fa9e4066Sahrens uint64_t db_blkid; 211fa9e4066Sahrens 212fa9e4066Sahrens /* 213fa9e4066Sahrens * Pointer to the blkptr_t which points to us. May be NULL if we 214fa9e4066Sahrens * don't have one yet. (NULL when evicted) 215fa9e4066Sahrens */ 216fa9e4066Sahrens blkptr_t *db_blkptr; 217fa9e4066Sahrens 218fa9e4066Sahrens /* 219fa9e4066Sahrens * Our indirection level. Data buffers have db_level==0. 220fa9e4066Sahrens * Indirect buffers which point to data buffers have 221fa9e4066Sahrens * db_level==1. etc. Buffers which contain dnodes have 222fa9e4066Sahrens * db_level==0, since the dnodes are stored in a file. 223fa9e4066Sahrens */ 224fa9e4066Sahrens uint8_t db_level; 225fa9e4066Sahrens 2269704bf7fSPaul Dagnelie /* 2279704bf7fSPaul Dagnelie * Protects db_buf's contents if they contain an indirect block or data 2289704bf7fSPaul Dagnelie * block of the meta-dnode. We use this lock to protect the structure of 2299704bf7fSPaul Dagnelie * the block tree. This means that when modifying this dbuf's data, we 2309704bf7fSPaul Dagnelie * grab its rwlock. When modifying its parent's data (including the 2319704bf7fSPaul Dagnelie * blkptr to this dbuf), we grab the parent's rwlock. The lock ordering 2329704bf7fSPaul Dagnelie * for this lock is: 2339704bf7fSPaul Dagnelie * 1) dn_struct_rwlock 2349704bf7fSPaul Dagnelie * 2) db_rwlock 2359704bf7fSPaul Dagnelie * We don't currently grab multiple dbufs' db_rwlocks at once. 2369704bf7fSPaul Dagnelie */ 2379704bf7fSPaul Dagnelie krwlock_t db_rwlock; 2389704bf7fSPaul Dagnelie 2399704bf7fSPaul Dagnelie /* buffer holding our data */ 2409704bf7fSPaul Dagnelie arc_buf_t *db_buf; 2419704bf7fSPaul Dagnelie 242fa9e4066Sahrens /* db_mtx protects the members below */ 243fa9e4066Sahrens kmutex_t db_mtx; 244fa9e4066Sahrens 245fa9e4066Sahrens /* 246fa9e4066Sahrens * Current state of the buffer 247fa9e4066Sahrens */ 248fa9e4066Sahrens dbuf_states_t db_state; 249fa9e4066Sahrens 250fa9e4066Sahrens /* 251fa9e4066Sahrens * Refcount accessed by dmu_buf_{hold,rele}. 252fa9e4066Sahrens * If nonzero, the buffer can't be destroyed. 253fa9e4066Sahrens * Protected by db_mtx. 254fa9e4066Sahrens */ 255e914ace2STim Schumacher zfs_refcount_t db_holds; 256fa9e4066Sahrens 257fa9e4066Sahrens kcondvar_t db_changed; 258c717a561Smaybee dbuf_dirty_record_t *db_data_pending; 259fa9e4066Sahrens 260c717a561Smaybee /* pointer to most recent dirty record for this buffer */ 261c717a561Smaybee dbuf_dirty_record_t *db_last_dirty; 262fa9e4066Sahrens 263fa9e4066Sahrens /* 264c717a561Smaybee * Our link on the owner dnodes's dn_dbufs list. 265ea8dc4b6Seschrock * Protected by its dn_dbufs_mtx. 266fa9e4066Sahrens */ 2670f6d88adSAlex Reece avl_node_t db_link; 268fa9e4066Sahrens 269adb52d92SMatthew Ahrens /* Link in dbuf_cache or dbuf_metadata_cache */ 270dcbf3bd6SGeorge Wilson multilist_node_t db_cache_link; 271dcbf3bd6SGeorge Wilson 272adb52d92SMatthew Ahrens /* Tells us which dbuf cache this dbuf is in, if any */ 273adb52d92SMatthew Ahrens dbuf_cached_state_t db_caching_status; 274adb52d92SMatthew Ahrens 275c717a561Smaybee /* Data which is unique to data (leaf) blocks: */ 276fa9e4066Sahrens 277bc9014e6SJustin Gibbs /* User callback information. */ 278bc9014e6SJustin Gibbs dmu_buf_user_t *db_user; 279c717a561Smaybee 280d2058105SJustin T. Gibbs /* 281d2058105SJustin T. Gibbs * Evict user data as soon as the dirty and reference 282d2058105SJustin T. Gibbs * counts are equal. 283d2058105SJustin T. Gibbs */ 284d2058105SJustin T. Gibbs uint8_t db_user_immediate_evict; 285d2058105SJustin T. Gibbs 286d2058105SJustin T. Gibbs /* 287d2058105SJustin T. Gibbs * This block was freed while a read or write was 288d2058105SJustin T. Gibbs * active. 289d2058105SJustin T. Gibbs */ 290c717a561Smaybee uint8_t db_freed_in_flight; 291c717a561Smaybee 292d2058105SJustin T. Gibbs /* 293d2058105SJustin T. Gibbs * dnode_evict_dbufs() or dnode_evict_bonus() tried to 294d2058105SJustin T. Gibbs * evict this dbuf, but couldn't due to outstanding 295d2058105SJustin T. Gibbs * references. Evict once the refcount drops to 0. 296d2058105SJustin T. Gibbs */ 297d2058105SJustin T. Gibbs uint8_t db_pending_evict; 298d2058105SJustin T. Gibbs 299c717a561Smaybee uint8_t db_dirtycnt; 300fa9e4066Sahrens } dmu_buf_impl_t; 301fa9e4066Sahrens 302fa9e4066Sahrens /* Note: the dbuf hash table is exposed only for the mdb module */ 303fa9e4066Sahrens #define DBUF_MUTEXES 256 304fa9e4066Sahrens #define DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)]) 305fa9e4066Sahrens typedef struct dbuf_hash_table { 306fa9e4066Sahrens uint64_t hash_table_mask; 307fa9e4066Sahrens dmu_buf_impl_t **hash_table; 308fa9e4066Sahrens kmutex_t hash_mutexes[DBUF_MUTEXES]; 309fa9e4066Sahrens } dbuf_hash_table_t; 310fa9e4066Sahrens 311*9e3493cbSJason King typedef void (*dbuf_prefetch_fn)(void *, boolean_t); 312*9e3493cbSJason King 313a2cdcdd2SPaul Dagnelie uint64_t dbuf_whichblock(struct dnode *di, int64_t level, uint64_t offset); 314fa9e4066Sahrens 315fa9e4066Sahrens dmu_buf_impl_t *dbuf_create_tlib(struct dnode *dn, char *data); 3161934e92fSmaybee void dbuf_create_bonus(struct dnode *dn); 3170a586ceaSMark Shellenbaum int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx); 3180a586ceaSMark Shellenbaum void dbuf_spill_hold(struct dnode *dn, dmu_buf_impl_t **dbp, void *tag); 3190a586ceaSMark Shellenbaum 3200a586ceaSMark Shellenbaum void dbuf_rm_spill(struct dnode *dn, dmu_tx_t *tx); 321fa9e4066Sahrens 322ea8dc4b6Seschrock dmu_buf_impl_t *dbuf_hold(struct dnode *dn, uint64_t blkid, void *tag); 323fa9e4066Sahrens dmu_buf_impl_t *dbuf_hold_level(struct dnode *dn, int level, uint64_t blkid, 324fa9e4066Sahrens void *tag); 325a2cdcdd2SPaul Dagnelie int dbuf_hold_impl(struct dnode *dn, uint8_t level, uint64_t blkid, 326a2cdcdd2SPaul Dagnelie boolean_t fail_sparse, boolean_t fail_uncached, 327fa9e4066Sahrens void *tag, dmu_buf_impl_t **dbp); 328fa9e4066Sahrens 329*9e3493cbSJason King int dbuf_prefetch_impl(struct dnode *dn, int64_t level, uint64_t blkid, 330*9e3493cbSJason King zio_priority_t prio, arc_flags_t aflags, dbuf_prefetch_fn cb, 331*9e3493cbSJason King void *arg); 332*9e3493cbSJason King int dbuf_prefetch(struct dnode *dn, int64_t level, uint64_t blkid, 333a2cdcdd2SPaul Dagnelie zio_priority_t prio, arc_flags_t aflags); 334fa9e4066Sahrens 335fa9e4066Sahrens void dbuf_add_ref(dmu_buf_impl_t *db, void *tag); 336e57a022bSJustin T. Gibbs boolean_t dbuf_try_add_ref(dmu_buf_t *db, objset_t *os, uint64_t obj, 337e57a022bSJustin T. Gibbs uint64_t blkid, void *tag); 338fa9e4066Sahrens uint64_t dbuf_refcount(dmu_buf_impl_t *db); 339fa9e4066Sahrens 340ea8dc4b6Seschrock void dbuf_rele(dmu_buf_impl_t *db, void *tag); 341c2919acbSMatthew Ahrens void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag, boolean_t evicting); 342fa9e4066Sahrens 343e57a022bSJustin T. Gibbs dmu_buf_impl_t *dbuf_find(struct objset *os, uint64_t object, uint8_t level, 344e57a022bSJustin T. Gibbs uint64_t blkid); 345fa9e4066Sahrens 346ea8dc4b6Seschrock int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags); 34782c9918fSTim Haley void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx); 348fa9e4066Sahrens void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx); 349fa9e4066Sahrens void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx); 3502fdbea25SAleksandr Guzovskiy void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx); 351c717a561Smaybee dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx); 352c242f9a0Schunli zhang - Sun Microsystems - Irvine United States arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db); 3535d7b4d43SMatthew Ahrens void dmu_buf_write_embedded(dmu_buf_t *dbuf, void *data, 3545d7b4d43SMatthew Ahrens bp_embedded_type_t etype, enum zio_compress comp, 3555d7b4d43SMatthew Ahrens int uncompressed_size, int compressed_size, int byteorder, dmu_tx_t *tx); 356fa9e4066Sahrens 357dcbf3bd6SGeorge Wilson void dbuf_destroy(dmu_buf_impl_t *db); 358fa9e4066Sahrens 359fa9e4066Sahrens void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx); 360c717a561Smaybee void dbuf_unoverride(dbuf_dirty_record_t *dr); 36146e1baa6SMatthew Ahrens void dbuf_sync_list(list_t *list, int level, dmu_tx_t *tx); 3623f9d6ad7SLin Ling void dbuf_release_bp(dmu_buf_impl_t *db); 3639704bf7fSPaul Dagnelie db_lock_type_t dmu_buf_lock_parent(dmu_buf_impl_t *db, krw_t rw, void *tag); 3649704bf7fSPaul Dagnelie void dmu_buf_unlock_parent(dmu_buf_impl_t *db, db_lock_type_t type, void *tag); 365fa9e4066Sahrens 3665cabbc6bSPrashanth Sreenivasa boolean_t dbuf_can_remap(const dmu_buf_impl_t *buf); 3675cabbc6bSPrashanth Sreenivasa 368cdb0ab79Smaybee void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end, 369fa9e4066Sahrens struct dmu_tx *); 370fa9e4066Sahrens 371fa9e4066Sahrens void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx); 372fa9e4066Sahrens 373744947dcSTom Erickson #define DB_DNODE(_db) ((_db)->db_dnode_handle->dnh_dnode) 374744947dcSTom Erickson #define DB_DNODE_LOCK(_db) ((_db)->db_dnode_handle->dnh_zrlock) 375744947dcSTom Erickson #define DB_DNODE_ENTER(_db) (zrl_add(&DB_DNODE_LOCK(_db))) 376744947dcSTom Erickson #define DB_DNODE_EXIT(_db) (zrl_remove(&DB_DNODE_LOCK(_db))) 377744947dcSTom Erickson #define DB_DNODE_HELD(_db) (!zrl_is_zero(&DB_DNODE_LOCK(_db))) 378744947dcSTom Erickson 379fa9e4066Sahrens void dbuf_init(void); 380fa9e4066Sahrens void dbuf_fini(void); 381fa9e4066Sahrens 382744947dcSTom Erickson boolean_t dbuf_is_metadata(dmu_buf_impl_t *db); 383744947dcSTom Erickson 384744947dcSTom Erickson #define DBUF_GET_BUFC_TYPE(_db) \ 3853b2aab18SMatthew Ahrens (dbuf_is_metadata(_db) ? ARC_BUFC_METADATA : ARC_BUFC_DATA) 3863baa08fcSek 387744947dcSTom Erickson #define DBUF_IS_CACHEABLE(_db) \ 388744947dcSTom Erickson ((_db)->db_objset->os_primary_cache == ZFS_CACHE_ALL || \ 3893b2aab18SMatthew Ahrens (dbuf_is_metadata(_db) && \ 390744947dcSTom Erickson ((_db)->db_objset->os_primary_cache == ZFS_CACHE_METADATA))) 3913baa08fcSek 392744947dcSTom Erickson #define DBUF_IS_L2CACHEABLE(_db) \ 393744947dcSTom Erickson ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_ALL || \ 3943b2aab18SMatthew Ahrens (dbuf_is_metadata(_db) && \ 395744947dcSTom Erickson ((_db)->db_objset->os_secondary_cache == ZFS_CACHE_METADATA))) 396ad23a2dbSjohansen 39727295216Sbenrubson #define DNODE_LEVEL_IS_L2CACHEABLE(_dn, _level) \ 39827295216Sbenrubson ((_dn)->dn_objset->os_secondary_cache == ZFS_CACHE_ALL || \ 39927295216Sbenrubson (((_level) > 0 || \ 40027295216Sbenrubson DMU_OT_IS_METADATA((_dn)->dn_handle->dnh_dnode->dn_type)) && \ 40127295216Sbenrubson ((_dn)->dn_objset->os_secondary_cache == ZFS_CACHE_METADATA))) 40227295216Sbenrubson 403fa9e4066Sahrens #ifdef ZFS_DEBUG 404fa9e4066Sahrens 405fa9e4066Sahrens /* 406fa9e4066Sahrens * There should be a ## between the string literal and fmt, to make it 407fbabab8fSmaybee * clear that we're joining two strings together, but gcc does not 408fbabab8fSmaybee * support that preprocessor token. 409fa9e4066Sahrens */ 410fa9e4066Sahrens #define dprintf_dbuf(dbuf, fmt, ...) do { \ 411fa9e4066Sahrens if (zfs_flags & ZFS_DEBUG_DPRINTF) { \ 412fa9e4066Sahrens char __db_buf[32]; \ 413fa9e4066Sahrens uint64_t __db_obj = (dbuf)->db.db_object; \ 414fa9e4066Sahrens if (__db_obj == DMU_META_DNODE_OBJECT) \ 415fa9e4066Sahrens (void) strcpy(__db_buf, "mdn"); \ 416fa9e4066Sahrens else \ 417fa9e4066Sahrens (void) snprintf(__db_buf, sizeof (__db_buf), "%lld", \ 418fa9e4066Sahrens (u_longlong_t)__db_obj); \ 419fa9e4066Sahrens dprintf_ds((dbuf)->db_objset->os_dsl_dataset, \ 420fa9e4066Sahrens "obj=%s lvl=%u blkid=%lld " fmt, \ 421fa9e4066Sahrens __db_buf, (dbuf)->db_level, \ 422fa9e4066Sahrens (u_longlong_t)(dbuf)->db_blkid, __VA_ARGS__); \ 423fa9e4066Sahrens } \ 424fa9e4066Sahrens _NOTE(CONSTCOND) } while (0) 425fa9e4066Sahrens 426fa9e4066Sahrens #define dprintf_dbuf_bp(db, bp, fmt, ...) do { \ 427fbabab8fSmaybee if (zfs_flags & ZFS_DEBUG_DPRINTF) { \ 428c0a81264Sek char *__blkbuf = kmem_alloc(BP_SPRINTF_LEN, KM_SLEEP); \ 42943466aaeSMax Grossman snprintf_blkptr(__blkbuf, BP_SPRINTF_LEN, bp); \ 430fa9e4066Sahrens dprintf_dbuf(db, fmt " %s\n", __VA_ARGS__, __blkbuf); \ 431c0a81264Sek kmem_free(__blkbuf, BP_SPRINTF_LEN); \ 432744947dcSTom Erickson } \ 433fa9e4066Sahrens _NOTE(CONSTCOND) } while (0) 434fa9e4066Sahrens 4359c9dc39aSek #define DBUF_VERIFY(db) dbuf_verify(db) 4369c9dc39aSek 437fa9e4066Sahrens #else 438fa9e4066Sahrens 439fa9e4066Sahrens #define dprintf_dbuf(db, fmt, ...) 440fa9e4066Sahrens #define dprintf_dbuf_bp(db, bp, fmt, ...) 4419c9dc39aSek #define DBUF_VERIFY(db) 442fa9e4066Sahrens 443fa9e4066Sahrens #endif 444fa9e4066Sahrens 445fa9e4066Sahrens 446fa9e4066Sahrens #ifdef __cplusplus 447fa9e4066Sahrens } 448fa9e4066Sahrens #endif 449fa9e4066Sahrens 450fa9e4066Sahrens #endif /* _SYS_DBUF_H */ 451