summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r--sys/kern/vfs_lookup.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index a291a25..6349c36 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -772,6 +772,14 @@ nextname:
if ((cnp->cn_flags & LOCKLEAF) == 0)
VOP_UNLOCK(dp, 0, td);
success:
+ /*
+ * Because of lookup_shared we may have the vnode shared locked, but
+ * the caller may want it to be exclusively locked.
+ */
+ if ((cnp->cn_flags & (ISLASTCN | LOCKSHARED | LOCKLEAF)) ==
+ (ISLASTCN | LOCKLEAF) && VOP_ISLOCKED(dp, td) != LK_EXCLUSIVE) {
+ vn_lock(dp, LK_UPGRADE | LK_RETRY, td);
+ }
if (vfslocked && dvfslocked)
VFS_UNLOCK_GIANT(dvfslocked); /* Only need one */
if (vfslocked || dvfslocked)
OpenPOWER on IntegriCloud