diff options
author | pjd <pjd@FreeBSD.org> | 2007-09-21 10:16:56 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2007-09-21 10:16:56 +0000 |
commit | 763f7449dc1d3190bc67d34d3c15c7d9702810a1 (patch) | |
tree | a5b1aba6df8555ac8e6d2f48e313aecb9a042293 /sys/kern/vfs_lookup.c | |
parent | 427fb1f9be8e582a99ba5f06375c89296481d692 (diff) | |
download | FreeBSD-src-763f7449dc1d3190bc67d34d3c15c7d9702810a1.zip FreeBSD-src-763f7449dc1d3190bc67d34d3c15c7d9702810a1.tar.gz |
Fix some locking cases where we ask for exclusively locked vnode, but we get
shared locked vnode in instead when vfs.lookup_shared is set to 1.
Discussed with: kib, kris
Tested by: kris
Approved by: re (kensmith)
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r-- | sys/kern/vfs_lookup.c | 8 |
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) |