diff options
author | truckman <truckman@FreeBSD.org> | 2002-09-19 13:32:45 +0000 |
---|---|---|
committer | truckman <truckman@FreeBSD.org> | 2002-09-19 13:32:45 +0000 |
commit | f2807820032fe586ea72f9048accb23a9d17c75f (patch) | |
tree | fed75b0fd3d3243127e21c52a13f663281ff50f1 /sys/fs/unionfs | |
parent | 38695c19fde9598c887707063c968842a2395e6c (diff) | |
download | FreeBSD-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.c | 23 |
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); } |