Print this page
patch first-pass


 516  * to the private data, other strategies can be employed if necessary
 517  * or convenient for the client (e.g. using container_of() to do the
 518  * conversion for private data that cannot have the dmu_buf_user_t as
 519  * its first member).
 520  *
 521  * Eviction callbacks are executed without the dbuf mutex held or any
 522  * other type of mechanism to guarantee that the dbuf is still available.
 523  * For this reason, users must assume the dbuf has already been freed
 524  * and not reference the dbuf from the callback context.
 525  *
 526  * Users requesting "immediate eviction" are notified as soon as the dbuf
 527  * is only referenced by dirty records (dirties == holds).  Otherwise the
 528  * notification occurs after eviction processing for the dbuf begins.
 529  */
 530 typedef struct dmu_buf_user {
 531         /*
 532          * Asynchronous user eviction callback state.
 533          */
 534         taskq_ent_t     dbu_tqent;
 535 
 536         /* This instance's eviction function pointer. */






 537         dmu_buf_evict_func_t *dbu_evict_func;
 538 #ifdef ZFS_DEBUG
 539         /*
 540          * Pointer to user's dbuf pointer.  NULL for clients that do
 541          * not associate a dbuf with their user data.
 542          *
 543          * The dbuf pointer is cleared upon eviction so as to catch
 544          * use-after-evict bugs in clients.
 545          */
 546         dmu_buf_t **dbu_clear_on_evict_dbufp;
 547 #endif
 548 } dmu_buf_user_t;
 549 
 550 /*
 551  * Initialize the given dmu_buf_user_t instance with the eviction function
 552  * evict_func, to be called when the user is evicted.
 553  *
 554  * NOTE: This function should only be called once on a given dmu_buf_user_t.
 555  *       To allow enforcement of this, dbu must already be zeroed on entry.
 556  */
 557 #ifdef __lint
 558 /* Very ugly, but it beats issuing suppression directives in many Makefiles. */
 559 extern void
 560 dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func,
 561     dmu_buf_t **clear_on_evict_dbufp);
 562 #else /* __lint */
 563 inline void
 564 dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func,
 565     dmu_buf_t **clear_on_evict_dbufp)
 566 {

 567         ASSERT(dbu->dbu_evict_func == NULL);
 568         ASSERT(evict_func != NULL);

 569         dbu->dbu_evict_func = evict_func;
 570 #ifdef ZFS_DEBUG
 571         dbu->dbu_clear_on_evict_dbufp = clear_on_evict_dbufp;
 572 #endif
 573 }
 574 #endif /* __lint */
 575 
 576 /*
 577  * Attach user data to a dbuf and mark it for normal (when the dbuf's
 578  * data is cleared or its reference count goes to zero) eviction processing.
 579  *
 580  * Returns NULL on success, or the existing user if another user currently
 581  * owns the buffer.
 582  */
 583 void *dmu_buf_set_user(dmu_buf_t *db, dmu_buf_user_t *user);
 584 
 585 /*
 586  * Attach user data to a dbuf and mark it for immediate (its dirty and
 587  * reference counts are equal) eviction processing.
 588  *




 516  * to the private data, other strategies can be employed if necessary
 517  * or convenient for the client (e.g. using container_of() to do the
 518  * conversion for private data that cannot have the dmu_buf_user_t as
 519  * its first member).
 520  *
 521  * Eviction callbacks are executed without the dbuf mutex held or any
 522  * other type of mechanism to guarantee that the dbuf is still available.
 523  * For this reason, users must assume the dbuf has already been freed
 524  * and not reference the dbuf from the callback context.
 525  *
 526  * Users requesting "immediate eviction" are notified as soon as the dbuf
 527  * is only referenced by dirty records (dirties == holds).  Otherwise the
 528  * notification occurs after eviction processing for the dbuf begins.
 529  */
 530 typedef struct dmu_buf_user {
 531         /*
 532          * Asynchronous user eviction callback state.
 533          */
 534         taskq_ent_t     dbu_tqent;
 535 
 536         /*
 537          * This instance's eviction function pointers.
 538          *
 539          * dbu_evict_func_prep is called synchronously while dbu_evict_func
 540          * is executed asynchronously on a taskq.
 541          */
 542         dmu_buf_evict_func_t *dbu_evict_func_prep;
 543         dmu_buf_evict_func_t *dbu_evict_func;
 544 #ifdef ZFS_DEBUG
 545         /*
 546          * Pointer to user's dbuf pointer.  NULL for clients that do
 547          * not associate a dbuf with their user data.
 548          *
 549          * The dbuf pointer is cleared upon eviction so as to catch
 550          * use-after-evict bugs in clients.
 551          */
 552         dmu_buf_t **dbu_clear_on_evict_dbufp;
 553 #endif
 554 } dmu_buf_user_t;
 555 
 556 /*
 557  * Initialize the given dmu_buf_user_t instance with the eviction function
 558  * evict_func, to be called when the user is evicted.
 559  *
 560  * NOTE: This function should only be called once on a given dmu_buf_user_t.
 561  *       To allow enforcement of this, dbu must already be zeroed on entry.
 562  */
 563 #ifdef __lint
 564 /* Very ugly, but it beats issuing suppression directives in many Makefiles. */
 565 extern void
 566 dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_prep,
 567     dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp);
 568 #else /* __lint */
 569 inline void
 570 dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_prep,
 571     dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp)
 572 {
 573         ASSERT(dbu->dbu_evict_func_prep == NULL);
 574         ASSERT(dbu->dbu_evict_func == NULL);
 575         ASSERT(evict_func != NULL);
 576         dbu->dbu_evict_func_prep = evict_func_prep;
 577         dbu->dbu_evict_func = evict_func;
 578 #ifdef ZFS_DEBUG
 579         dbu->dbu_clear_on_evict_dbufp = clear_on_evict_dbufp;
 580 #endif
 581 }
 582 #endif /* __lint */
 583 
 584 /*
 585  * Attach user data to a dbuf and mark it for normal (when the dbuf's
 586  * data is cleared or its reference count goes to zero) eviction processing.
 587  *
 588  * Returns NULL on success, or the existing user if another user currently
 589  * owns the buffer.
 590  */
 591 void *dmu_buf_set_user(dmu_buf_t *db, dmu_buf_user_t *user);
 592 
 593 /*
 594  * Attach user data to a dbuf and mark it for immediate (its dirty and
 595  * reference counts are equal) eviction processing.
 596  *