Print this page
patch first-pass


  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);