aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/zfs/arc.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c
index d49d85db0..6c9164f76 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);
}