@@ -6623,6 +6623,39 @@ arc_release(arc_buf_t *buf, const void *tag)
6623
6623
kmutex_t * hash_lock = HDR_LOCK (hdr );
6624
6624
mutex_enter (hash_lock );
6625
6625
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
+
6626
6659
/*
6627
6660
* This assignment is only valid as long as the hash_lock is
6628
6661
* held, we must be careful not to reference state or the
0 commit comments