Print this page
3752 want more verifiable dbuf user eviction
Submitted by:   Justin Gibbs <justing@spectralogic.com>
Submitted by:   Will Andrews <willa@spectralogic.com>


 200          */
 201         refcount_t db_holds;
 202 
 203         /* buffer holding our data */
 204         arc_buf_t *db_buf;
 205 
 206         kcondvar_t db_changed;
 207         dbuf_dirty_record_t *db_data_pending;
 208 
 209         /* pointer to most recent dirty record for this buffer */
 210         dbuf_dirty_record_t *db_last_dirty;
 211 
 212         /*
 213          * Our link on the owner dnodes's dn_dbufs list.
 214          * Protected by its dn_dbufs_mtx.
 215          */
 216         list_node_t db_link;
 217 
 218         /* Data which is unique to data (leaf) blocks: */
 219 
 220         /* stuff we store for the user (see dmu_buf_set_user) */
 221         void *db_user_ptr;
 222         void **db_user_data_ptr_ptr;
 223         dmu_buf_evict_func_t *db_evict_func;
 224 
 225         uint8_t db_immediate_evict;
 226         uint8_t db_freed_in_flight;
 227 
 228         uint8_t db_dirtycnt;
 229 } dmu_buf_impl_t;
 230 
 231 /* Note: the dbuf hash table is exposed only for the mdb module */
 232 #define DBUF_MUTEXES 256
 233 #define DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)])
 234 typedef struct dbuf_hash_table {
 235         uint64_t hash_table_mask;
 236         dmu_buf_impl_t **hash_table;
 237         kmutex_t hash_mutexes[DBUF_MUTEXES];
 238 } dbuf_hash_table_t;
 239 
 240 
 241 uint64_t dbuf_whichblock(struct dnode *di, uint64_t offset);
 242 
 243 dmu_buf_impl_t *dbuf_create_tlib(struct dnode *dn, char *data);


 256 void dbuf_prefetch(struct dnode *dn, uint64_t blkid);
 257 
 258 void dbuf_add_ref(dmu_buf_impl_t *db, void *tag);
 259 uint64_t dbuf_refcount(dmu_buf_impl_t *db);
 260 
 261 void dbuf_rele(dmu_buf_impl_t *db, void *tag);
 262 void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag);
 263 
 264 dmu_buf_impl_t *dbuf_find(struct dnode *dn, uint8_t level, uint64_t blkid);
 265 
 266 int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags);
 267 void dbuf_will_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 268 void dbuf_fill_done(dmu_buf_impl_t *db, dmu_tx_t *tx);
 269 void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx);
 270 void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx);
 271 void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx);
 272 void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx);
 273 dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 274 arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);
 275 
 276 void dbuf_clear(dmu_buf_impl_t *db);
 277 void dbuf_evict(dmu_buf_impl_t *db);
 278 
 279 void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 280 void dbuf_unoverride(dbuf_dirty_record_t *dr);
 281 void dbuf_sync_list(list_t *list, dmu_tx_t *tx);
 282 void dbuf_release_bp(dmu_buf_impl_t *db);
 283 
 284 void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end,
 285     struct dmu_tx *);
 286 
 287 void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx);
 288 
 289 #define DB_DNODE(_db)           ((_db)->db_dnode_handle->dnh_dnode)
 290 #define DB_DNODE_LOCK(_db)      ((_db)->db_dnode_handle->dnh_zrlock)
 291 #define DB_DNODE_ENTER(_db)     (zrl_add(&DB_DNODE_LOCK(_db)))
 292 #define DB_DNODE_EXIT(_db)      (zrl_remove(&DB_DNODE_LOCK(_db)))
 293 #define DB_DNODE_HELD(_db)      (!zrl_is_zero(&DB_DNODE_LOCK(_db)))
 294 #define DB_GET_SPA(_spa_p, _db) {               \
 295         dnode_t *__dn;                          \
 296         DB_DNODE_ENTER(_db);                    \
 297         __dn = DB_DNODE(_db);                   \




 200          */
 201         refcount_t db_holds;
 202 
 203         /* buffer holding our data */
 204         arc_buf_t *db_buf;
 205 
 206         kcondvar_t db_changed;
 207         dbuf_dirty_record_t *db_data_pending;
 208 
 209         /* pointer to most recent dirty record for this buffer */
 210         dbuf_dirty_record_t *db_last_dirty;
 211 
 212         /*
 213          * Our link on the owner dnodes's dn_dbufs list.
 214          * Protected by its dn_dbufs_mtx.
 215          */
 216         list_node_t db_link;
 217 
 218         /* Data which is unique to data (leaf) blocks: */
 219 
 220         /* User callback information.  See dmu_buf_set_user(). */
 221         dmu_buf_user_t *db_user;


 222 
 223         uint8_t db_immediate_evict;
 224         uint8_t db_freed_in_flight;
 225 
 226         uint8_t db_dirtycnt;
 227 } dmu_buf_impl_t;
 228 
 229 /* Note: the dbuf hash table is exposed only for the mdb module */
 230 #define DBUF_MUTEXES 256
 231 #define DBUF_HASH_MUTEX(h, idx) (&(h)->hash_mutexes[(idx) & (DBUF_MUTEXES-1)])
 232 typedef struct dbuf_hash_table {
 233         uint64_t hash_table_mask;
 234         dmu_buf_impl_t **hash_table;
 235         kmutex_t hash_mutexes[DBUF_MUTEXES];
 236 } dbuf_hash_table_t;
 237 
 238 
 239 uint64_t dbuf_whichblock(struct dnode *di, uint64_t offset);
 240 
 241 dmu_buf_impl_t *dbuf_create_tlib(struct dnode *dn, char *data);


 254 void dbuf_prefetch(struct dnode *dn, uint64_t blkid);
 255 
 256 void dbuf_add_ref(dmu_buf_impl_t *db, void *tag);
 257 uint64_t dbuf_refcount(dmu_buf_impl_t *db);
 258 
 259 void dbuf_rele(dmu_buf_impl_t *db, void *tag);
 260 void dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag);
 261 
 262 dmu_buf_impl_t *dbuf_find(struct dnode *dn, uint8_t level, uint64_t blkid);
 263 
 264 int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags);
 265 void dbuf_will_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 266 void dbuf_fill_done(dmu_buf_impl_t *db, dmu_tx_t *tx);
 267 void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx);
 268 void dmu_buf_will_fill(dmu_buf_t *db, dmu_tx_t *tx);
 269 void dmu_buf_fill_done(dmu_buf_t *db, dmu_tx_t *tx);
 270 void dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx);
 271 dbuf_dirty_record_t *dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 272 arc_buf_t *dbuf_loan_arcbuf(dmu_buf_impl_t *db);
 273 
 274 void dbuf_clear(dmu_buf_impl_t *db, list_t *evict_list_p);
 275 void dbuf_evict(dmu_buf_impl_t *db, list_t *evict_list_p);
 276 
 277 void dbuf_setdirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
 278 void dbuf_unoverride(dbuf_dirty_record_t *dr);
 279 void dbuf_sync_list(list_t *list, dmu_tx_t *tx);
 280 void dbuf_release_bp(dmu_buf_impl_t *db);
 281 
 282 void dbuf_free_range(struct dnode *dn, uint64_t start, uint64_t end,
 283     struct dmu_tx *);
 284 
 285 void dbuf_new_size(dmu_buf_impl_t *db, int size, dmu_tx_t *tx);
 286 
 287 #define DB_DNODE(_db)           ((_db)->db_dnode_handle->dnh_dnode)
 288 #define DB_DNODE_LOCK(_db)      ((_db)->db_dnode_handle->dnh_zrlock)
 289 #define DB_DNODE_ENTER(_db)     (zrl_add(&DB_DNODE_LOCK(_db)))
 290 #define DB_DNODE_EXIT(_db)      (zrl_remove(&DB_DNODE_LOCK(_db)))
 291 #define DB_DNODE_HELD(_db)      (!zrl_is_zero(&DB_DNODE_LOCK(_db)))
 292 #define DB_GET_SPA(_spa_p, _db) {               \
 293         dnode_t *__dn;                          \
 294         DB_DNODE_ENTER(_db);                    \
 295         __dn = DB_DNODE(_db);                   \