summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorMatthew Macy <[email protected]>2019-12-16 09:49:05 -0800
committerBrian Behlendorf <[email protected]>2019-12-16 09:49:05 -0800
commitba434b18ec6bcedb9d9eb39fa234fbba55032381 (patch)
treea51ec94689c201e0ca18c6c45d8090d081a8ad90 /module/zfs
parentddb4e69db5eb0ed741dc4e32714af3e0f054086c (diff)
Fix zfs_xattr_owner_unlinked on FreeBSD and comment
Explain FreeBSD VFS' unfortunate idiosyncratic locking requirements. There is no functional change for other platforms. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Matt Macy <[email protected]> Closes #9720
Diffstat (limited to 'module/zfs')
-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.