summaryrefslogtreecommitdiffstats
path: root/sys/fs/unionfs
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/fs/unionfs
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/fs/unionfs')
-rw-r--r--sys/fs/unionfs/union_vnops.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
index 92d92ed..9d0d2a1 100644
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -1224,8 +1224,8 @@ union_remove(ap)
/*
* union_link:
*
- * tdvp will be locked on entry, vp will not be locked on entry.
- * tdvp should remain locked on return and vp should remain unlocked
+ * tdvp and vp will be locked on entry.
+ * tdvp and vp should remain locked on return.
* on return.
*/
@@ -1250,7 +1250,6 @@ union_link(ap)
struct union_node *tun = VTOUNION(ap->a_vp);
if (tun->un_uppervp == NULLVP) {
- vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
#if 0
if (dun->un_uppervp == tun->un_dirvp) {
if (dun->un_flags & UN_ULOCK) {
@@ -1267,14 +1266,13 @@ union_link(ap)
dun->un_flags |= UN_ULOCK;
}
#endif
- VOP_UNLOCK(ap->a_vp, 0, td);
+ if (error)
+ return (error);
}
vp = tun->un_uppervp;
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
}
- if (error)
- return (error);
-
/*
* Make sure upper is locked, then unlock the union directory we were
* called with to avoid a deadlock while we are calling VOP_LINK on
@@ -1289,11 +1287,20 @@ union_link(ap)
error = VOP_LINK(tdvp, vp, cnp); /* call link on upper */
/*
+ * Unlock tun->un_uppervp if we locked it above.
+ */
+ if (ap->a_tdvp->v_op == ap->a_vp->v_op)
+ VOP_UNLOCK(vp, 0, td);
+ /*
* We have to unlock tdvp prior to relocking our calling node in
- * order to avoid a deadlock.
+ * order to avoid a deadlock. We also have to unlock ap->a_vp
+ * before relocking the directory, but then we have to relock
+ * ap->a_vp as our caller expects.
*/
+ VOP_UNLOCK(ap->a_vp, 0, td);
union_unlock_upper(tdvp, td);
vn_lock(ap->a_tdvp, LK_EXCLUSIVE | LK_RETRY, td);
+ vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
return (error);
}
OpenPOWER on IntegriCloud