From 2a49ebbb4dd0799ffa4fcb4043220a0f992aa68c Mon Sep 17 00:00:00 2001 From: George Amanakis Date: Thu, 16 Sep 2021 18:40:15 +0200 Subject: [PATCH] Avoid panic in case of pool errors and missing L2ARC 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 Reviewed-by: Alexander Motin Signed-off-by: George Amanakis Closes #12392 --- module/zfs/arc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 6acd36313..f0330150f 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -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);