Skip to content

Commit

Permalink
Avoid panic in case of pool errors and missing L2ARC
Browse files Browse the repository at this point in the history
In case an ARC buffer is allocated only on L2ARC, and there are
underlying errors in a pool with the cache device in faulty state, a
panic can occur in arc_read_done()->arc_hdr_destroy()->
arc_hdr_l2arc_destroy()->arc_hdr_clear_flags() when trying to free
the ARC buffer.

Fix this by discarding the buffer's identity in arc_hdr_destroy(), in
case the buffer is not empty, before calling arc_hdr_l2hdr_destroy().

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: George Amanakis <gamanakis@gmail.com>
Closes #12392
  • Loading branch information
gamanakis authored Sep 16, 2021
1 parent 6065740 commit 2a49ebb
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3775,8 +3775,13 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
* to acquire the l2ad_mtx. If that happens, we don't
* want to re-destroy the header's L2 portion.
*/
if (HDR_HAS_L2HDR(hdr))
if (HDR_HAS_L2HDR(hdr)) {

if (!HDR_EMPTY(hdr))
buf_discard_identity(hdr);

arc_hdr_l2hdr_destroy(hdr);
}

if (!buflist_held)
mutex_exit(&dev->l2ad_mtx);
Expand Down

0 comments on commit 2a49ebb

Please sign in to comment.