FreeBSD ZFS
The Zettabyte File System

sys/dbuf.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) 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 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines