summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/zfs/zfs_log.c8
-rw-r--r--module/zfs/zfs_replay.c10
2 files changed, 18 insertions, 0 deletions
diff --git a/module/zfs/zfs_log.c b/module/zfs/zfs_log.c
index 21296c76e..cfb2f3be2 100644
--- a/module/zfs/zfs_log.c
+++ b/module/zfs/zfs_log.c
@@ -232,7 +232,13 @@ zfs_xattr_owner_unlinked(znode_t *zp)
int unlinked = 0;
znode_t *dzp;
+ /*
+ * zrele drops the vnode lock which violates the VOP locking contract
+ * on FreeBSD. See comment at the top of zfs_replay.c for more detail.
+ */
+#ifndef __FreeBSD__
zhold(zp);
+#endif
/*
* if zp is XATTR node, keep walking up via z_xattr_parent until we
* get the owner
@@ -247,7 +253,9 @@ zfs_xattr_owner_unlinked(znode_t *zp)
zp = dzp;
unlinked = zp->z_unlinked;
}
+#ifndef __FreeBSD__
zrele(zp);
+#endif
return (unlinked);
}
diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c
index 59a219983..6372c004a 100644
--- a/module/zfs/zfs_replay.c
+++ b/module/zfs/zfs_replay.c
@@ -49,6 +49,16 @@
#include <sys/zpl.h>
/*
+ * NB: FreeBSD expects to be able to do vnode locking in lookup and
+ * hold the locks across all subsequent VOPs until vput is called.
+ * This means that its zfs vnops routines can't do any internal locking.
+ * In order to have the same contract as the Linux vnops there would
+ * needed to be duplicate locked vnops. If the vnops were used more widely
+ * in common code this would likely be preferable. However, currently
+ * this is the only file where this is the case.
+ */
+
+/*
* Functions to replay ZFS intent log (ZIL) records
* The functions are called through a function vector (zfs_replay_vector)
* which is indexed by the transaction type.