Skip to content

Commit 3de7aeb

Browse files
gamanakisbehlendorf
authored andcommitted
Avoid deadlock when removing L2ARC devices under I/O
In case we have I/O and try to remove an L2ARC device a deadlock might occur. arc_read()->zio_read()->zfs_blkptr_verify() waits for SCL_VDEV to be dropped while holding the hash_lock. However, spa_l2cache_load() holds SCL_ALL and waits for the hash_lock in l2arc_evict(). Fix this by moving zfs_blkptr_verify() to the top top arc_read() before the hash_lock is taken. Verify the block pointer and return a checksum error if damaged rather than halting the system, by using BLK_VERIFY_LOG instead of BLK_VERIFY_HALT. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Mark Maybee <[email protected]> Signed-off-by: George Amanakis <[email protected]> Closes #12054
1 parent ff64096 commit 3de7aeb

File tree

2 files changed

+6
-14
lines changed

2 files changed

+6
-14
lines changed

module/zfs/arc.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5949,6 +5949,12 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
59495949
* Embedded BP's have no DVA and require no I/O to "read".
59505950
* Create an anonymous arc buf to back it.
59515951
*/
5952+
if (!zfs_blkptr_verify(spa, bp, zio_flags &
5953+
ZIO_FLAG_CONFIG_WRITER, BLK_VERIFY_LOG)) {
5954+
rc = SET_ERROR(ECKSUM);
5955+
goto out;
5956+
}
5957+
59525958
hdr = buf_hash_find(guid, bp, &hash_lock);
59535959
}
59545960

@@ -6120,17 +6126,6 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
61206126
goto out;
61216127
}
61226128

6123-
/*
6124-
* Gracefully handle a damaged logical block size as a
6125-
* checksum error.
6126-
*/
6127-
if (lsize > spa_maxblocksize(spa)) {
6128-
rc = SET_ERROR(ECKSUM);
6129-
if (hash_lock != NULL)
6130-
mutex_exit(hash_lock);
6131-
goto out;
6132-
}
6133-
61346129
if (hdr == NULL) {
61356130
/*
61366131
* This block is not in the cache or it has

module/zfs/zio.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,9 +1107,6 @@ zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
11071107
{
11081108
zio_t *zio;
11091109

1110-
(void) zfs_blkptr_verify(spa, bp, flags & ZIO_FLAG_CONFIG_WRITER,
1111-
BLK_VERIFY_HALT);
1112-
11131110
zio = zio_create(pio, spa, BP_PHYSICAL_BIRTH(bp), bp,
11141111
data, size, size, done, private,
11151112
ZIO_TYPE_READ, priority, flags, NULL, 0, zb,

0 commit comments

Comments
 (0)