@@ -6623,6 +6623,39 @@ arc_release(arc_buf_t *buf, const void *tag)
66236623 kmutex_t * hash_lock = HDR_LOCK (hdr );
66246624 mutex_enter (hash_lock );
66256625
6626+ /*
6627+ * Wait for any other IO for this hdr, as additional
6628+ * buf(s) could be about to appear, in which case
6629+ * we would not want to transition hdr to arc_anon.
6630+ */
6631+ while (HDR_IO_IN_PROGRESS (hdr )) {
6632+ arc_callback_t * acb ;
6633+
6634+ DTRACE_PROBE1 (arc_release__io , arc_buf_hdr_t * , hdr );
6635+
6636+ acb = kmem_zalloc (sizeof (arc_callback_t ), KM_SLEEP );
6637+ acb -> acb_wait = B_TRUE ;
6638+ mutex_init (& acb -> acb_wait_lock , NULL , MUTEX_DEFAULT , NULL );
6639+ cv_init (& acb -> acb_wait_cv , NULL , CV_DEFAULT , NULL );
6640+
6641+ acb -> acb_zio_head = hdr -> b_l1hdr .b_acb -> acb_zio_head ;
6642+ acb -> acb_next = hdr -> b_l1hdr .b_acb ;
6643+ hdr -> b_l1hdr .b_acb -> acb_prev = acb ;
6644+ hdr -> b_l1hdr .b_acb = acb ;
6645+
6646+ mutex_exit (hash_lock );
6647+ mutex_enter (& acb -> acb_wait_lock );
6648+ while (acb -> acb_wait )
6649+ cv_wait (& acb -> acb_wait_cv , & acb -> acb_wait_lock );
6650+
6651+ mutex_exit (& acb -> acb_wait_lock );
6652+ mutex_destroy (& acb -> acb_wait_lock );
6653+ cv_destroy (& acb -> acb_wait_cv );
6654+ kmem_free (acb , sizeof (arc_callback_t ));
6655+
6656+ mutex_enter (hash_lock );
6657+ }
6658+
66266659 /*
66276660 * This assignment is only valid as long as the hash_lock is
66286661 * held, we must be careful not to reference state or the
0 commit comments