summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2002-06-28 20:06:47 +0000
committeriedowse <iedowse@FreeBSD.org>2002-06-28 20:06:47 +0000
commit792737cf4d98d3af06c2946642a2cf3409e03e1b (patch)
treebae8117b476354108de4855889b02267fea89758 /sys
parent3d67b562831b016305d6434fbec32de963646692 (diff)
downloadFreeBSD-src-792737cf4d98d3af06c2946642a2cf3409e03e1b.zip
FreeBSD-src-792737cf4d98d3af06c2946642a2cf3409e03e1b.tar.gz
In vn_mkdir(), use vrele() instead of vput() on the parent directory
vnode in the case that the target exists and is the same vnode as the parent (i.e. "mkdir ."). The namei() call does not leave the vnode locked in this case even though you might expect it to. This bug was mostly harmless in practice because unlocking an already unlocked vnode currently does not trigger any panics or warnings. Reviewed by: jeff
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_extattr.c10
-rw-r--r--sys/kern/vfs_syscalls.c10
2 files changed, 18 insertions, 2 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 05e4fb6..41e4d28 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -3652,7 +3652,15 @@ restart:
if (vp != NULL) {
NDFREE(&nd, NDF_ONLY_PNBUF);
vrele(vp);
- vput(nd.ni_dvp);
+ /*
+ * XXX namei called with LOCKPARENT but not LOCKLEAF has
+ * the strange behaviour of leaving the vnode unlocked
+ * if the target is the same vnode as the parent.
+ */
+ if (vp == nd.ni_dvp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
return (EEXIST);
}
if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 05e4fb6..41e4d28 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3652,7 +3652,15 @@ restart:
if (vp != NULL) {
NDFREE(&nd, NDF_ONLY_PNBUF);
vrele(vp);
- vput(nd.ni_dvp);
+ /*
+ * XXX namei called with LOCKPARENT but not LOCKLEAF has
+ * the strange behaviour of leaving the vnode unlocked
+ * if the target is the same vnode as the parent.
+ */
+ if (vp == nd.ni_dvp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
return (EEXIST);
}
if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
OpenPOWER on IntegriCloud