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 *
|