Print this page
patch first-pass

@@ -531,11 +531,17 @@
         /*
          * Asynchronous user eviction callback state.
          */
         taskq_ent_t     dbu_tqent;
 
-        /* This instance's eviction function pointer. */
+        /*
+         * This instance's eviction function pointers.
+         *
+         * dbu_evict_func_prep is called synchronously while dbu_evict_func
+         * is executed asynchronously on a taskq.
+         */
+        dmu_buf_evict_func_t *dbu_evict_func_prep;
         dmu_buf_evict_func_t *dbu_evict_func;
 #ifdef ZFS_DEBUG
         /*
          * Pointer to user's dbuf pointer.  NULL for clients that do
          * not associate a dbuf with their user data.

@@ -555,19 +561,21 @@
  *       To allow enforcement of this, dbu must already be zeroed on entry.
  */
 #ifdef __lint
 /* Very ugly, but it beats issuing suppression directives in many Makefiles. */
 extern void
-dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func,
-    dmu_buf_t **clear_on_evict_dbufp);
+dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_prep,
+    dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp);
 #else /* __lint */
 inline void
-dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func,
-    dmu_buf_t **clear_on_evict_dbufp)
+dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_prep,
+    dmu_buf_evict_func_t *evict_func, dmu_buf_t **clear_on_evict_dbufp)
 {
+        ASSERT(dbu->dbu_evict_func_prep == NULL);
         ASSERT(dbu->dbu_evict_func == NULL);
         ASSERT(evict_func != NULL);
+        dbu->dbu_evict_func_prep = evict_func_prep;
         dbu->dbu_evict_func = evict_func;
 #ifdef ZFS_DEBUG
         dbu->dbu_clear_on_evict_dbufp = clear_on_evict_dbufp;
 #endif
 }