41 #include <sys/zio.h>
42 #include <sys/dmu_zfetch.h>
43 #include <sys/sa.h>
44 #include <sys/sa_impl.h>
45 #include <sys/zfeature.h>
46 #include <sys/blkptr.h>
47 #include <sys/range_tree.h>
48
49 /*
50 * Number of times that zfs_free_range() took the slow path while doing
51 * a zfs receive. A nonzero value indicates a potential performance problem.
52 */
53 uint64_t zfs_free_range_recv_miss;
54
55 static void dbuf_destroy(dmu_buf_impl_t *db);
56 static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
57 static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
58
59 #ifndef __lint
60 extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
61 dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp);
62 #endif /* ! __lint */
63
64 /*
65 * Global data structures and functions for the dbuf cache.
66 */
67 static kmem_cache_t *dbuf_cache;
68 static taskq_t *dbu_evict_taskq;
69
70 /* ARGSUSED */
71 static int
72 dbuf_cons(void *vdb, void *unused, int kmflag)
73 {
74 dmu_buf_impl_t *db = vdb;
75 bzero(db, sizeof (dmu_buf_impl_t));
76
77 mutex_init(&db->db_mtx, NULL, MUTEX_DEFAULT, NULL);
78 cv_init(&db->db_changed, NULL, CV_DEFAULT, NULL);
79 refcount_create(&db->db_holds);
80
81 return (0);
281 #endif
282 }
283
284 static void
285 dbuf_evict_user(dmu_buf_impl_t *db)
286 {
287 dmu_buf_user_t *dbu = db->db_user;
288
289 ASSERT(MUTEX_HELD(&db->db_mtx));
290
291 if (dbu == NULL)
292 return;
293
294 dbuf_verify_user(db, DBVU_EVICTING);
295 db->db_user = NULL;
296
297 #ifdef ZFS_DEBUG
298 if (dbu->dbu_clear_on_evict_dbufp != NULL)
299 *dbu->dbu_clear_on_evict_dbufp = NULL;
300 #endif
301
302 /*
303 * Invoke the callback from a taskq to avoid lock order reversals
304 * and limit stack depth.
305 */
306 taskq_dispatch_ent(dbu_evict_taskq, dbu->dbu_evict_func, dbu, 0,
307 &dbu->dbu_tqent);
308 }
309
310 boolean_t
311 dbuf_is_metadata(dmu_buf_impl_t *db)
312 {
313 if (db->db_level > 0) {
314 return (B_TRUE);
315 } else {
316 boolean_t is_metadata;
317
318 DB_DNODE_ENTER(db);
319 is_metadata = DMU_OT_IS_METADATA(DB_DNODE(db)->dn_type);
320 DB_DNODE_EXIT(db);
|
41 #include <sys/zio.h>
42 #include <sys/dmu_zfetch.h>
43 #include <sys/sa.h>
44 #include <sys/sa_impl.h>
45 #include <sys/zfeature.h>
46 #include <sys/blkptr.h>
47 #include <sys/range_tree.h>
48
49 /*
50 * Number of times that zfs_free_range() took the slow path while doing
51 * a zfs receive. A nonzero value indicates a potential performance problem.
52 */
53 uint64_t zfs_free_range_recv_miss;
54
55 static void dbuf_destroy(dmu_buf_impl_t *db);
56 static boolean_t dbuf_undirty(dmu_buf_impl_t *db, dmu_tx_t *tx);
57 static void dbuf_write(dbuf_dirty_record_t *dr, arc_buf_t *data, dmu_tx_t *tx);
58
59 #ifndef __lint
60 extern inline void dmu_buf_init_user(dmu_buf_user_t *dbu,
61 dmu_buf_evict_func_t *evict_func_prep, dmu_buf_evict_func_t *evict_func,
62 dmu_buf_t **clear_on_evict_dbufp);
63 #endif /* ! __lint */
64
65 /*
66 * Global data structures and functions for the dbuf cache.
67 */
68 static kmem_cache_t *dbuf_cache;
69 static taskq_t *dbu_evict_taskq;
70
71 /* ARGSUSED */
72 static int
73 dbuf_cons(void *vdb, void *unused, int kmflag)
74 {
75 dmu_buf_impl_t *db = vdb;
76 bzero(db, sizeof (dmu_buf_impl_t));
77
78 mutex_init(&db->db_mtx, NULL, MUTEX_DEFAULT, NULL);
79 cv_init(&db->db_changed, NULL, CV_DEFAULT, NULL);
80 refcount_create(&db->db_holds);
81
82 return (0);
282 #endif
283 }
284
285 static void
286 dbuf_evict_user(dmu_buf_impl_t *db)
287 {
288 dmu_buf_user_t *dbu = db->db_user;
289
290 ASSERT(MUTEX_HELD(&db->db_mtx));
291
292 if (dbu == NULL)
293 return;
294
295 dbuf_verify_user(db, DBVU_EVICTING);
296 db->db_user = NULL;
297
298 #ifdef ZFS_DEBUG
299 if (dbu->dbu_clear_on_evict_dbufp != NULL)
300 *dbu->dbu_clear_on_evict_dbufp = NULL;
301 #endif
302
303 if (dbu->dbu_evict_func_prep != NULL)
304 dbu->dbu_evict_func_prep(dbu);
305
306 /*
307 * Invoke the callback from a taskq to avoid lock order reversals
308 * and limit stack depth.
309 */
310 taskq_dispatch_ent(dbu_evict_taskq, dbu->dbu_evict_func, dbu, 0,
311 &dbu->dbu_tqent);
312 }
313
314 boolean_t
315 dbuf_is_metadata(dmu_buf_impl_t *db)
316 {
317 if (db->db_level > 0) {
318 return (B_TRUE);
319 } else {
320 boolean_t is_metadata;
321
322 DB_DNODE_ENTER(db);
323 is_metadata = DMU_OT_IS_METADATA(DB_DNODE(db)->dn_type);
324 DB_DNODE_EXIT(db);
|