diff --git a/module/zfs/arc.c b/module/zfs/arc.c index d49d85db03..6c9164f76b 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -5540,6 +5540,17 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, ASSERT(!BP_IS_HOLE(bp)); ASSERT(!BP_IS_REDACTED(bp)); + /* + * Normally SPL_FSTRANS will already be set since kernel threads which + * expect to call the DMU interfaces will set it when created. System + * calls are similarly handled by setting/cleaning the bit in the + * registered callback (module/os/.../zfs/zpl_*). + * + * External consumers such as Lustre which call the exported DMU + * interfaces may not have set SPL_FSTRANS. To avoid a deadlock + * on the hash_lock always set and clear the bit. + */ + fstrans_cookie_t cookie = spl_fstrans_mark(); top: if (!embedded_bp) { /* @@ -6014,6 +6025,7 @@ out: /* embedded bps don't actually go to disk */ if (!embedded_bp) spa_read_history_add(spa, zb, *arc_flags); + spl_fstrans_unmark(cookie); return (rc); }