summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1997-04-13 06:29:13 +0000
committerphk <phk@FreeBSD.org>1997-04-13 06:29:13 +0000
commit4292ccaf6dc17167b3168e3ddf5b1a5e6c818486 (patch)
tree35ae49f1acf641744a886c2216a878b83b576229 /sys
parent69934522f723a52b4a83a27a0996b92a17c0a9a2 (diff)
downloadFreeBSD-src-4292ccaf6dc17167b3168e3ddf5b1a5e6c818486.zip
FreeBSD-src-4292ccaf6dc17167b3168e3ddf5b1a5e6c818486.tar.gz
The function union_fsync tries to lock overlaying vnode object when
dolock is not set (that is, targetvp == overlaying vnode object). Current code use FIXUP macro to do this, and never unlocks overlaying vnode object in union_fsync. So, the vnode object will be locked twice and never unlocked. PR: 3271 Submitted by: kato
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/unionfs/union_vnops.c17
-rw-r--r--sys/miscfs/union/union_vnops.c17
2 files changed, 28 insertions, 6 deletions
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
index 7909706..b97cc79 100644
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union_vnops.c 8.32 (Berkeley) 6/23/95
- * $Id: union_vnops.c,v 1.19 1997/02/22 09:40:42 peter Exp $
+ * $Id: union_vnops.c,v 1.20 1997/03/23 03:37:00 bde Exp $
*/
#include <sys/param.h>
@@ -917,17 +917,28 @@ union_fsync(ap)
int error = 0;
struct proc *p = ap->a_p;
struct vnode *targetvp = OTHERVP(ap->a_vp);
+ struct union_node *un;
+ int isupperlocked = 0;
if (targetvp != NULLVP) {
int dolock = (targetvp == LOWERVP(ap->a_vp));
+ un = VTOUNION(ap->a_vp);
if (dolock)
vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p);
- else
- FIXUP(VTOUNION(ap->a_vp), p);
+ else if ((un->un_flags & UN_ULOCK) == 0 &&
+ VOP_ISLOCKED(targetvp) == 0) {
+ isupperlocked = 1;
+ vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p);
+ un->un_flags |= UN_ULOCK;
+ }
error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, p);
if (dolock)
VOP_UNLOCK(targetvp, 0, p);
+ else if (isupperlocked) {
+ VOP_UNLOCK(targetvp, 0, p);
+ un->un_flags &= ~UN_ULOCK;
+ }
}
return (error);
diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c
index 7909706..b97cc79 100644
--- a/sys/miscfs/union/union_vnops.c
+++ b/sys/miscfs/union/union_vnops.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union_vnops.c 8.32 (Berkeley) 6/23/95
- * $Id: union_vnops.c,v 1.19 1997/02/22 09:40:42 peter Exp $
+ * $Id: union_vnops.c,v 1.20 1997/03/23 03:37:00 bde Exp $
*/
#include <sys/param.h>
@@ -917,17 +917,28 @@ union_fsync(ap)
int error = 0;
struct proc *p = ap->a_p;
struct vnode *targetvp = OTHERVP(ap->a_vp);
+ struct union_node *un;
+ int isupperlocked = 0;
if (targetvp != NULLVP) {
int dolock = (targetvp == LOWERVP(ap->a_vp));
+ un = VTOUNION(ap->a_vp);
if (dolock)
vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p);
- else
- FIXUP(VTOUNION(ap->a_vp), p);
+ else if ((un->un_flags & UN_ULOCK) == 0 &&
+ VOP_ISLOCKED(targetvp) == 0) {
+ isupperlocked = 1;
+ vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p);
+ un->un_flags |= UN_ULOCK;
+ }
error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, p);
if (dolock)
VOP_UNLOCK(targetvp, 0, p);
+ else if (isupperlocked) {
+ VOP_UNLOCK(targetvp, 0, p);
+ un->un_flags &= ~UN_ULOCK;
+ }
}
return (error);
OpenPOWER on IntegriCloud