summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2002-09-19 13:32:45 +0000
committertruckman <truckman@FreeBSD.org>2002-09-19 13:32:45 +0000
commitf2807820032fe586ea72f9048accb23a9d17c75f (patch)
treefed75b0fd3d3243127e21c52a13f663281ff50f1 /sys/kern
parent38695c19fde9598c887707063c968842a2395e6c (diff)
downloadFreeBSD-src-f2807820032fe586ea72f9048accb23a9d17c75f.zip
FreeBSD-src-f2807820032fe586ea72f9048accb23a9d17c75f.tar.gz
VOP_FSYNC() requires that it's vnode argument be locked, which nfs_link()
wasn't doing. Rather than just lock and unlock the vnode around the call to VOP_FSYNC(), implement rwatson's suggestion to lock the file vnode in kern_link() before calling VOP_LINK(), since the other filesystems also locked the file vnode right away in their link methods. Remove the locking and and unlocking from the leaf filesystem link methods. Reviewed by: rwatson, bde (except for the unionfs_link() changes)
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_extattr.c4
-rw-r--r--sys/kern/vfs_syscalls.c4
-rw-r--r--sys/kern/vnode_if.src2
3 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index e1b2d7f..5ad587c 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -1027,10 +1027,12 @@ kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg)
if (nd.ni_vp != NULL) {
vrele(nd.ni_vp);
error = EEXIST;
- } else {
+ } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td))
+ == 0) {
VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
+ VOP_UNLOCK(vp, 0, td);
}
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_dvp);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index e1b2d7f..5ad587c 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1027,10 +1027,12 @@ kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg)
if (nd.ni_vp != NULL) {
vrele(nd.ni_vp);
error = EEXIST;
- } else {
+ } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td))
+ == 0) {
VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
+ VOP_UNLOCK(vp, 0, td);
}
NDFREE(&nd, NDF_ONLY_PNBUF);
vput(nd.ni_dvp);
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 3202058..28b5d2e 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -261,7 +261,7 @@ vop_remove {
#
#% link tdvp L L L
-#% link vp U U U
+#% link vp L L L
#
vop_link {
IN struct vnode *tdvp;
OpenPOWER on IntegriCloud