@@ -6449,27 +6449,11 @@ arc_release(arc_buf_t *buf, const void *tag)
64496449 arc_state_t * state = hdr -> b_l1hdr .b_state ;
64506450 ASSERT3P (hash_lock , = = , HDR_LOCK (hdr ));
64516451 ASSERT3P (state , != , arc_anon );
6452+ ASSERT3P (state , != , arc_l2c_only );
64526453
64536454 /* this buffer is not on any list */
64546455 ASSERT3S (zfs_refcount_count (& hdr -> b_l1hdr .b_refcnt ), > , 0 );
64556456
6456- if (HDR_HAS_L2HDR (hdr )) {
6457- mutex_enter (& hdr -> b_l2hdr .b_dev -> l2ad_mtx );
6458-
6459- /*
6460- * We have to recheck this conditional again now that
6461- * we're holding the l2ad_mtx to prevent a race with
6462- * another thread which might be concurrently calling
6463- * l2arc_evict(). In that case, l2arc_evict() might have
6464- * destroyed the header's L2 portion as we were waiting
6465- * to acquire the l2ad_mtx.
6466- */
6467- if (HDR_HAS_L2HDR (hdr ))
6468- arc_hdr_l2hdr_destroy (hdr );
6469-
6470- mutex_exit (& hdr -> b_l2hdr .b_dev -> l2ad_mtx );
6471- }
6472-
64736457 /*
64746458 * Do we have more than one buf?
64756459 */
@@ -6481,21 +6465,17 @@ arc_release(arc_buf_t *buf, const void *tag)
64816465 boolean_t protected = HDR_PROTECTED (hdr );
64826466 enum zio_compress compress = arc_hdr_get_compress (hdr );
64836467 arc_buf_contents_t type = arc_buf_type (hdr );
6484- VERIFY3U (hdr -> b_type , = = , type );
6485-
6486- ASSERT (hdr -> b_l1hdr .b_buf != buf || buf -> b_next != NULL );
6487- VERIFY3S (remove_reference (hdr , tag ), > , 0 );
64886468
64896469 if (ARC_BUF_SHARED (buf ) && !ARC_BUF_COMPRESSED (buf )) {
64906470 ASSERT3P (hdr -> b_l1hdr .b_buf , != , buf );
64916471 ASSERT (ARC_BUF_LAST (buf ));
64926472 }
64936473
64946474 /*
6495- * Pull the data off of this hdr and attach it to
6496- * a new anonymous hdr. Also find the last buffer
6475+ * Pull the buffer off of this hdr and find the last buffer
64976476 * in the hdr's buffer list.
64986477 */
6478+ VERIFY3S (remove_reference (hdr , tag ), > , 0 );
64996479 arc_buf_t * lastbuf = arc_buf_remove (hdr , buf );
65006480 ASSERT3P (lastbuf , != , NULL );
65016481
@@ -6504,7 +6484,6 @@ arc_release(arc_buf_t *buf, const void *tag)
65046484 * buffer, then we must stop sharing that block.
65056485 */
65066486 if (ARC_BUF_SHARED (buf )) {
6507- ASSERT3P (hdr -> b_l1hdr .b_buf , != , buf );
65086487 ASSERT (!arc_buf_is_shared (lastbuf ));
65096488
65106489 /*
@@ -6526,7 +6505,6 @@ arc_release(arc_buf_t *buf, const void *tag)
65266505 abd_copy_from_buf (hdr -> b_l1hdr .b_pabd ,
65276506 buf -> b_data , psize );
65286507 }
6529- VERIFY3P (lastbuf -> b_data , != , NULL );
65306508 } else if (HDR_SHARED_DATA (hdr )) {
65316509 /*
65326510 * Uncompressed shared buffers are always at the end
@@ -6542,18 +6520,10 @@ arc_release(arc_buf_t *buf, const void *tag)
65426520 }
65436521
65446522 ASSERT (hdr -> b_l1hdr .b_pabd != NULL || HDR_HAS_RABD (hdr ));
6545- ASSERT3P (state , != , arc_l2c_only );
65466523
65476524 (void ) zfs_refcount_remove_many (& state -> arcs_size [type ],
65486525 arc_buf_size (buf ), buf );
65496526
6550- if (zfs_refcount_is_zero (& hdr -> b_l1hdr .b_refcnt )) {
6551- ASSERT3P (state , != , arc_l2c_only );
6552- (void ) zfs_refcount_remove_many (
6553- & state -> arcs_esize [type ],
6554- arc_buf_size (buf ), buf );
6555- }
6556-
65576527 arc_cksum_verify (buf );
65586528 arc_buf_unwatch (buf );
65596529
@@ -6581,6 +6551,15 @@ arc_release(arc_buf_t *buf, const void *tag)
65816551 /* protected by hash lock, or hdr is on arc_anon */
65826552 ASSERT (!multilist_link_active (& hdr -> b_l1hdr .b_arc_node ));
65836553 ASSERT (!HDR_IO_IN_PROGRESS (hdr ));
6554+
6555+ if (HDR_HAS_L2HDR (hdr )) {
6556+ mutex_enter (& hdr -> b_l2hdr .b_dev -> l2ad_mtx );
6557+ /* Recheck to prevent race with l2arc_evict(). */
6558+ if (HDR_HAS_L2HDR (hdr ))
6559+ arc_hdr_l2hdr_destroy (hdr );
6560+ mutex_exit (& hdr -> b_l2hdr .b_dev -> l2ad_mtx );
6561+ }
6562+
65846563 hdr -> b_l1hdr .b_mru_hits = 0 ;
65856564 hdr -> b_l1hdr .b_mru_ghost_hits = 0 ;
65866565 hdr -> b_l1hdr .b_mfu_hits = 0 ;
0 commit comments