summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorbp <bp@FreeBSD.org>2000-09-25 15:24:04 +0000
committerbp <bp@FreeBSD.org>2000-09-25 15:24:04 +0000
commit6110b03d2438de0cb3f47dbce3cec5c1dfa712f6 (patch)
tree104536559087d506b1c196e2562f5ecc57690734 /sys/kern
parent520f10057961f03f20c2b980adff11bbfa8c2d6d (diff)
downloadFreeBSD-src-6110b03d2438de0cb3f47dbce3cec5c1dfa712f6.zip
FreeBSD-src-6110b03d2438de0cb3f47dbce3cec5c1dfa712f6.tar.gz
Add a lock structure to vnode structure. Previously it was either allocated
separately (nfs, cd9660 etc) or keept as a first element of structure referenced by v_data pointer(ffs). Such organization leads to known problems with stacked filesystems. From this point vop_no*lock*() functions maintain only interlock lock. vop_std*lock*() functions maintain built-in v_lock structure using lockmgr(). vop_sharedlock() is compatible with vop_stdunlock(), but maintains a shared lock on vnode. If filesystem wishes to export lockmgr compatible lock, it can put an address of this lock to v_vnlock field. This indicates that the upper filesystem can take advantage of it and use single lock structure for entire (or part) of stack of vnodes. This field shouldn't be examined or modified by VFS code except for initialization purposes. Reviewed in general by: mckusick
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_default.c70
-rw-r--r--sys/kern/vfs_export.c9
-rw-r--r--sys/kern/vfs_subr.c9
3 files changed, 28 insertions, 60 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 2b651c8..01418f0 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -231,19 +231,13 @@ vop_stdlock(ap)
struct proc *a_p;
} */ *ap;
{
- struct lock *l;
-
- if ((l = (struct lock *)ap->a_vp->v_data) == NULL) {
- if (ap->a_flags & LK_INTERLOCK)
- simple_unlock(&ap->a_vp->v_interlock);
- return 0;
- }
+ struct vnode *vp = ap->a_vp;
#ifndef DEBUG_LOCKS
- return (lockmgr(l, ap->a_flags, &ap->a_vp->v_interlock, ap->a_p));
+ return (lockmgr(&vp->v_lock, ap->a_flags, &vp->v_interlock, ap->a_p));
#else
- return (debuglockmgr(l, ap->a_flags, &ap->a_vp->v_interlock, ap->a_p,
- "vop_stdlock", ap->a_vp->filename, ap->a_vp->line));
+ return (debuglockmgr(&vp->v_lock, ap->a_flags, &vp->v_interlock,
+ ap->a_p, "vop_stdlock", vp->filename, vp->line));
#endif
}
@@ -255,15 +249,9 @@ vop_stdunlock(ap)
struct proc *a_p;
} */ *ap;
{
- struct lock *l;
-
- if ((l = (struct lock *)ap->a_vp->v_data) == NULL) {
- if (ap->a_flags & LK_INTERLOCK)
- simple_unlock(&ap->a_vp->v_interlock);
- return 0;
- }
+ struct vnode *vp = ap->a_vp;
- return (lockmgr(l, ap->a_flags | LK_RELEASE, &ap->a_vp->v_interlock,
+ return (lockmgr(&vp->v_lock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
ap->a_p));
}
@@ -274,12 +262,8 @@ vop_stdislocked(ap)
struct proc *a_p;
} */ *ap;
{
- struct lock *l;
- if ((l = (struct lock *)ap->a_vp->v_data) == NULL)
- return 0;
-
- return (lockstatus(l, ap->a_p));
+ return (lockstatus(&ap->a_vp->v_lock, ap->a_p));
}
int
@@ -374,13 +358,6 @@ vop_sharedlock(ap)
struct vnode *vp = ap->a_vp;
int vnflags, flags = ap->a_flags;
- if (vp->v_vnlock == NULL) {
- if ((flags & LK_TYPE_MASK) == LK_DRAIN)
- return (0);
- MALLOC(vp->v_vnlock, struct lock *, sizeof(struct lock),
- M_VNODE, M_WAITOK);
- lockinit(vp->v_vnlock, PVFS, "vnlock", 0, LK_NOPAUSE);
- }
switch (flags & LK_TYPE_MASK) {
case LK_DRAIN:
vnflags = LK_DRAIN;
@@ -408,9 +385,9 @@ vop_sharedlock(ap)
if (flags & LK_INTERLOCK)
vnflags |= LK_INTERLOCK;
#ifndef DEBUG_LOCKS
- return (lockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p));
+ return (lockmgr(&vp->v_lock, vnflags, &vp->v_interlock, ap->a_p));
#else
- return (debuglockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p,
+ return (debuglockmgr(&vp->v_lock, vnflags, &vp->v_interlock, ap->a_p,
"vop_sharedlock", vp->filename, vp->line));
#endif
}
@@ -447,13 +424,6 @@ vop_nolock(ap)
struct vnode *vp = ap->a_vp;
int vnflags, flags = ap->a_flags;
- if (vp->v_vnlock == NULL) {
- if ((flags & LK_TYPE_MASK) == LK_DRAIN)
- return (0);
- MALLOC(vp->v_vnlock, struct lock *, sizeof(struct lock),
- M_VNODE, M_WAITOK);
- lockinit(vp->v_vnlock, PVFS, "vnlock", 0, LK_NOPAUSE);
- }
switch (flags & LK_TYPE_MASK) {
case LK_DRAIN:
vnflags = LK_DRAIN;
@@ -472,7 +442,7 @@ vop_nolock(ap)
}
if (flags & LK_INTERLOCK)
vnflags |= LK_INTERLOCK;
- return(lockmgr(vp->v_vnlock, vnflags, &vp->v_interlock, ap->a_p));
+ return(lockmgr(&vp->v_lock, vnflags, &vp->v_interlock, ap->a_p));
#else /* for now */
/*
* Since we are not using the lock manager, we must clear
@@ -495,15 +465,14 @@ vop_nounlock(ap)
struct proc *a_p;
} */ *ap;
{
- struct vnode *vp = ap->a_vp;
- if (vp->v_vnlock == NULL) {
- if (ap->a_flags & LK_INTERLOCK)
- simple_unlock(&ap->a_vp->v_interlock);
- return (0);
- }
- return (lockmgr(vp->v_vnlock, LK_RELEASE | ap->a_flags,
- &ap->a_vp->v_interlock, ap->a_p));
+ /*
+ * Since we are not using the lock manager, we must clear
+ * the interlock here.
+ */
+ if (ap->a_flags & LK_INTERLOCK)
+ simple_unlock(&ap->a_vp->v_interlock);
+ return (0);
}
/*
@@ -516,11 +485,8 @@ vop_noislocked(ap)
struct proc *a_p;
} */ *ap;
{
- struct vnode *vp = ap->a_vp;
- if (vp->v_vnlock == NULL)
- return (0);
- return (lockstatus(vp->v_vnlock, ap->a_p));
+ return (0);
}
/*
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index e0a758c..6d60d44 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -618,6 +618,7 @@ getnewvnode(tag, mp, vops, vpp)
vp->v_type = VNON;
vp->v_tag = tag;
vp->v_op = vops;
+ lockinit(&vp->v_lock, PVFS, "vnlock", 0, LK_NOPAUSE);
insmntque(vp, mp);
*vpp = vp;
vp->v_usecount = 1;
@@ -1373,6 +1374,9 @@ addaliasu(nvp, nvp_rdev)
ops = nvp->v_op;
nvp->v_op = ovp->v_op;
ovp->v_op = ops;
+ lockinit(&ovp->v_lock, PVFS, "vnlock", 0, LK_NOPAUSE);
+ if (nvp->v_vnlock)
+ ovp->v_vnlock = &ovp->v_lock;
insmntque(ovp, nvp->v_mount);
vrele(nvp);
vgone(nvp);
@@ -1773,10 +1777,7 @@ vclean(vp, flags, p)
}
cache_purge(vp);
- if (vp->v_vnlock) {
- FREE(vp->v_vnlock, M_VNODE);
- vp->v_vnlock = NULL;
- }
+ vp->v_vnlock = NULL;
if (VSHOULDFREE(vp))
vfree(vp);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index e0a758c..6d60d44 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -618,6 +618,7 @@ getnewvnode(tag, mp, vops, vpp)
vp->v_type = VNON;
vp->v_tag = tag;
vp->v_op = vops;
+ lockinit(&vp->v_lock, PVFS, "vnlock", 0, LK_NOPAUSE);
insmntque(vp, mp);
*vpp = vp;
vp->v_usecount = 1;
@@ -1373,6 +1374,9 @@ addaliasu(nvp, nvp_rdev)
ops = nvp->v_op;
nvp->v_op = ovp->v_op;
ovp->v_op = ops;
+ lockinit(&ovp->v_lock, PVFS, "vnlock", 0, LK_NOPAUSE);
+ if (nvp->v_vnlock)
+ ovp->v_vnlock = &ovp->v_lock;
insmntque(ovp, nvp->v_mount);
vrele(nvp);
vgone(nvp);
@@ -1773,10 +1777,7 @@ vclean(vp, flags, p)
}
cache_purge(vp);
- if (vp->v_vnlock) {
- FREE(vp->v_vnlock, M_VNODE);
- vp->v_vnlock = NULL;
- }
+ vp->v_vnlock = NULL;
if (VSHOULDFREE(vp))
vfree(vp);
OpenPOWER on IntegriCloud