summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/spec_vnops.c8
-rw-r--r--sys/kern/vfs_bio.c18
-rw-r--r--sys/kern/vfs_subr.c245
-rw-r--r--sys/kern/vfs_sync.c6
-rw-r--r--sys/miscfs/specfs/spec_vnops.c8
-rw-r--r--sys/nfs/nfs_nqlease.c13
-rw-r--r--sys/nfs/nfs_vnops.c20
-rw-r--r--sys/sys/buf.h6
-rw-r--r--sys/sys/vnode.h70
-rw-r--r--sys/ufs/ffs/ffs_softdep.c8
-rw-r--r--sys/ufs/ffs/ffs_vnops.c9
-rw-r--r--sys/uvm/uvm_swap.c42
-rw-r--r--sys/vm/vm_swap.c20
13 files changed, 219 insertions, 254 deletions
diff --git a/sys/kern/spec_vnops.c b/sys/kern/spec_vnops.c
index 234073b5d61..5d6281fc865 100644
--- a/sys/kern/spec_vnops.c
+++ b/sys/kern/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spec_vnops.c,v 1.16 2001/02/23 14:42:39 csapuntz Exp $ */
+/* $OpenBSD: spec_vnops.c,v 1.17 2001/02/24 19:07:10 csapuntz Exp $ */
/* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */
/*
@@ -511,10 +511,8 @@ loop:
goto loop;
}
if (ap->a_waitfor == MNT_WAIT) {
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
- }
+ vwaitforio (vp, 0, "spec_fsync", 0);
+
#ifdef DIAGNOSTIC
if (vp->v_dirtyblkhd.lh_first) {
splx(s);
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 405a1173f6d..950af98a639 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_bio.c,v 1.30 2001/02/23 14:52:50 csapuntz Exp $ */
+/* $OpenBSD: vfs_bio.c,v 1.31 2001/02/24 19:07:08 csapuntz Exp $ */
/* $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $ */
/*-
@@ -338,7 +338,7 @@ bwrite(bp)
*/
if (wasdelayed) {
--numdirtybufs;
- reassignbuf(bp, bp->b_vp);
+ reassignbuf(bp);
} else
curproc->p_stats->p_ru.ru_oublock++;
@@ -393,7 +393,7 @@ bdwrite(bp)
if (!ISSET(bp->b_flags, B_DELWRI)) {
SET(bp->b_flags, B_DELWRI);
s = splbio();
- reassignbuf(bp, bp->b_vp);
+ reassignbuf(bp);
++numdirtybufs;
splx(s);
curproc->p_stats->p_ru.ru_oublock++; /* XXX */
@@ -433,7 +433,7 @@ buf_dirty(bp)
{
if (ISSET(bp->b_flags, B_DELWRI) == 0) {
SET(bp->b_flags, B_DELWRI);
- reassignbuf(bp, bp->b_vp);
+ reassignbuf(bp);
++numdirtybufs;
}
}
@@ -447,7 +447,7 @@ buf_undirty(bp)
{
if (ISSET(bp->b_flags, B_DELWRI)) {
CLR(bp->b_flags, B_DELWRI);
- reassignbuf(bp, bp->b_vp);
+ reassignbuf(bp);
--numdirtybufs;
}
}
@@ -506,7 +506,7 @@ brelse(bp)
}
if (bp->b_vp) {
- reassignbuf(bp, bp->b_vp);
+ reassignbuf(bp);
brelvp(bp);
}
if (bp->b_bufsize <= 0)
@@ -895,8 +895,10 @@ biodone(bp)
if (LIST_FIRST(&bp->b_dep) != NULL)
buf_complete(bp);
- if (!ISSET(bp->b_flags, B_READ)) /* wake up reader */
- vwakeup(bp);
+ if (!ISSET(bp->b_flags, B_READ)) {
+ CLR(bp->b_flags, B_WRITEINPROG);
+ vwakeup(bp->b_vp);
+ }
if (ISSET(bp->b_flags, B_CALL)) { /* if necessary, call out */
CLR(bp->b_flags, B_CALL); /* but note callout done */
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index abb8b66970f..5b6ca33f3c9 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.50 2001/02/23 14:42:37 csapuntz Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.51 2001/02/24 19:07:08 csapuntz Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -105,6 +105,7 @@ struct simplelock mntvnode_slock;
struct simplelock vnode_free_list_slock;
struct simplelock spechash_slock;
+void vclean __P((struct vnode *, int, struct proc *));
void insmntque __P((struct vnode *, struct mount *));
int getdevvp __P((dev_t, struct vnode **, enum vtype));
@@ -368,9 +369,7 @@ getnewvnode(tag, mp, vops, vpp)
struct freelst *listhd;
static int toggle;
struct vnode *vp;
-#ifdef DIAGNOSTIC
int s;
-#endif
/*
* We must choose whether to allocate a new vnode or recycle an
@@ -393,9 +392,11 @@ getnewvnode(tag, mp, vops, vpp)
simple_lock(&vnode_free_list_slock);
+ s = splbio();
if ((numvnodes < desiredvnodes) ||
((TAILQ_FIRST(listhd = &vnode_free_list) == NULL) &&
((TAILQ_FIRST(listhd = &vnode_hold_list) == NULL) || toggle))) {
+ splx(s);
simple_unlock(&vnode_free_list_slock);
vp = (struct vnode *)malloc((u_long)sizeof *vp,
M_VNODE, M_WAITOK);
@@ -413,6 +414,7 @@ getnewvnode(tag, mp, vops, vpp)
* locked, so this is close enough to being empty.
*/
if (vp == NULLVP) {
+ splx(s);
simple_unlock(&vnode_free_list_slock);
tablefull("vnode");
*vpp = 0;
@@ -424,7 +426,8 @@ getnewvnode(tag, mp, vops, vpp)
}
TAILQ_REMOVE(listhd, vp, v_freelist);
- vp->v_flag &= ~VONFREELIST;
+ vp->v_bioflag &= ~VBIOONFREELIST;
+ splx(s);
simple_unlock(&vnode_free_list_slock);
if (vp->v_type != VBAD)
@@ -442,6 +445,7 @@ getnewvnode(tag, mp, vops, vpp)
splx(s);
#endif
vp->v_flag = 0;
+ vp->v_bioflag = 0;
vp->v_socket = 0;
}
vp->v_type = VNON;
@@ -647,6 +651,7 @@ vget(vp, flags, p)
struct proc *p;
{
int error;
+ int s;
/*
* If the vnode is in the process of being cleaned out for
* another use, we wait for the cleaning to finish and then
@@ -663,14 +668,17 @@ vget(vp, flags, p)
tsleep((caddr_t)vp, PINOD, "vget", 0);
return (ENOENT);
}
- if ((vp->v_flag & VONFREELIST) && (vp->v_usecount == 0)) {
+ if (vp->v_usecount == 0 &&
+ (vp->v_bioflag & VBIOONFREELIST)) {
+ s = splbio();
simple_lock(&vnode_free_list_slock);
if (vp->v_holdcnt > 0)
TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
else
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
simple_unlock(&vnode_free_list_slock);
- vp->v_flag &= ~VONFREELIST;
+ vp->v_bioflag &= ~VBIOONFREELIST;
+ splx(s);
}
vp->v_usecount++;
if (flags & LK_TYPE_MASK) {
@@ -704,31 +712,31 @@ vref(vp)
}
#endif /* DIAGNOSTIC */
+
+/*
+ * Must be called at splbio
+ */
static __inline__ void
vputonfreelist(vp)
struct vnode *vp;
{
+ int s;
struct freelst *lst;
- /*
- * insert at tail of LRU list
- */
+ s = splbio();
#ifdef DIAGNOSTIC
- if (vp->v_usecount != 0) {
+ if (vp->v_usecount != 0)
panic("Use count is not zero!");
- }
-
- if (vp->v_flag & VONFREELIST) {
+
+ if (vp->v_bioflag & VBIOONFREELIST) {
vprint ("vnode already on free list: ", vp);
panic ("vnode already on free list");
- return;
}
#endif
- vp->v_flag |= VONFREELIST;
- simple_lock(&vnode_free_list_slock);
+ vp->v_bioflag |= VBIOONFREELIST;
if (vp->v_holdcnt > 0)
lst = &vnode_hold_list;
@@ -739,9 +747,9 @@ vputonfreelist(vp)
if (vp->v_type == VBAD)
TAILQ_INSERT_HEAD(lst, vp, v_freelist);
else
- TAILQ_INSERT_TAIL(lst, vp, v_freelist);
+ TAILQ_INSERT_TAIL(lst, vp, v_freelist);
- simple_unlock(&vnode_free_list_slock);
+ splx(s);
}
/*
@@ -770,6 +778,7 @@ vput(vp)
panic("vput: ref cnt");
}
#endif
+
vputonfreelist(vp);
simple_unlock(&vp->v_interlock);
@@ -803,13 +812,15 @@ vrele(vp)
panic("vrele: ref cnt");
}
#endif
+
vputonfreelist(vp);
if (vn_lock(vp, LK_EXCLUSIVE|LK_INTERLOCK, p) == 0)
VOP_INACTIVE(vp, p);
}
-#ifdef DIAGNOSTIC
+void vhold __P((struct vnode *vp));
+
/*
* Page or buffer structure gets a reference.
*/
@@ -823,7 +834,7 @@ vhold(vp)
* zero, move it to the hold list.
*/
simple_lock(&vp->v_interlock);
- if ((vp->v_flag & VONFREELIST) &&
+ if ((vp->v_bioflag & VBIOONFREELIST) &&
vp->v_holdcnt == 0 && vp->v_usecount == 0) {
simple_lock(&vnode_free_list_slock);
TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
@@ -835,33 +846,6 @@ vhold(vp)
}
/*
- * Page or buffer structure frees a reference.
- */
-void
-holdrele(vp)
- register struct vnode *vp;
-{
-
- simple_lock(&vp->v_interlock);
- if (vp->v_holdcnt <= 0)
- panic("holdrele: holdcnt");
- vp->v_holdcnt--;
- /*
- * If it is on the holdlist and the hold count drops to
- * zero, move it to the free list.
- */
- if ((vp->v_flag & VONFREELIST) &&
- vp->v_holdcnt == 0 && vp->v_usecount == 0) {
- simple_lock(&vnode_free_list_slock);
- TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
- simple_unlock(&vnode_free_list_slock);
- }
- simple_unlock(&vp->v_interlock);
-}
-#endif /* DIAGNOSTIC */
-
-/*
* Remove any vnodes in the vnode table belonging to mount point mp.
*
* If MNT_NOFORCE is specified, there should not be any active ones,
@@ -1082,6 +1066,7 @@ vrecycle(vp, inter_lkp, p)
return (0);
}
+
/*
* Eliminate all activity associated with a vnode
* in preparation for reuse.
@@ -1170,15 +1155,24 @@ vgonel(vp, p)
*/
vp->v_type = VBAD;
- if ((vp->v_flag & VONFREELIST) &&
- vp->v_usecount == 0) {
+ /*
+ * Move onto the free list, unless we were called from
+ * getnewvnode and we're not on any free list
+ */
+ if (vp->v_usecount == 0 &&
+ (vp->v_bioflag & VBIOONFREELIST)) {
+ int s;
simple_lock(&vnode_free_list_slock);
+ s = splbio();
+
if (vp->v_holdcnt > 0)
- panic("vgonel: not clean");
- if (TAILQ_FIRST(&vnode_free_list) != vp) {
- TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
- TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
- }
+ panic("vgonel: not clean");
+
+ if (TAILQ_FIRST(&vnode_free_list) != vp) {
+ TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
+ TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
+ }
+ splx(s);
simple_unlock(&vnode_free_list_slock);
}
}
@@ -1285,8 +1279,8 @@ vprint(label, vp)
strcat(buf, "|VXLOCK");
if (vp->v_flag & VXWANT)
strcat(buf, "|VXWANT");
- if (vp->v_flag & VBWAIT)
- strcat(buf, "|VBWAIT");
+ if (vp->v_bioflag & VBIOWAIT)
+ strcat(buf, "| VBIOWAIT");
if (vp->v_flag & VALIASED)
strcat(buf, "|VALIASED");
if (buf[0] != '\0')
@@ -1875,22 +1869,44 @@ fs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
*/
/*
+ * Wait for all outstanding I/Os to complete
+ *
+ * Manipulates v_numoutput. Must be called at splbio()
+ */
+int
+vwaitforio(vp, slpflag, wchan, timeo)
+ struct vnode *vp;
+ int slpflag, timeo;
+ char *wchan;
+{
+ int error = 0;
+
+ while (vp->v_numoutput) {
+ vp->v_bioflag |= VBIOWAIT;
+ error = tsleep((caddr_t)&vp->v_numoutput,
+ slpflag | (PRIBIO + 1), wchan, timeo);
+ if (error)
+ break;
+ }
+
+ return (error);
+}
+
+
+/*
* Update outstanding I/O count and do wakeup if requested.
*
* Manipulates v_numoutput. Must be called at splbio()
*/
void
-vwakeup(bp)
- register struct buf *bp;
+vwakeup(vp)
+ struct vnode *vp;
{
- register struct vnode *vp;
-
- bp->b_flags &= ~B_WRITEINPROG;
- if ((vp = bp->b_vp) != NULL) {
+ if (vp != NULL) {
if (--vp->v_numoutput < 0)
panic("vwakeup: neg numoutput");
- if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
- vp->v_flag &= ~VBWAIT;
+ if ((vp->v_bioflag & VBIOWAIT) && vp->v_numoutput <= 0) {
+ vp->v_bioflag &= ~VBIOWAIT;
wakeup((caddr_t)&vp->v_numoutput);
}
}
@@ -1914,10 +1930,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
if (flags & V_SAVE) {
s = splbio();
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
- }
+ vwaitforio(vp, 0, "vinvalbuf", 0);
if (vp->v_dirtyblkhd.lh_first != NULL) {
splx(s);
if ((error = VOP_FSYNC(vp, cred, MNT_WAIT, p)) != 0)
@@ -2012,15 +2025,13 @@ loop:
splx(s);
return;
}
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "vflushbuf", 0);
- }
- splx(s);
+ vwaitforio(vp, 0, "vflushbuf", 0);
if (vp->v_dirtyblkhd.lh_first != NULL) {
+ splx(s);
vprint("vflushbuf: dirty", vp);
goto loop;
}
+ splx(s);
}
/*
@@ -2036,7 +2047,7 @@ bgetvp(vp, bp)
if (bp->b_vp)
panic("bgetvp: not free");
- VHOLD(vp);
+ vhold(vp);
bp->b_vp = vp;
if (vp->v_type == VBLK || vp->v_type == VCHR)
bp->b_dev = vp->v_rdev;
@@ -2066,31 +2077,79 @@ brelvp(bp)
*/
if (bp->b_vnbufs.le_next != NOLIST)
bufremvn(bp);
- if ((vp->v_flag & VONSYNCLIST) &&
+ if ((vp->v_bioflag & VBIOONSYNCLIST) &&
LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
- vp->v_flag &= ~VONSYNCLIST;
+ vp->v_bioflag &= ~VBIOONSYNCLIST;
LIST_REMOVE(vp, v_synclist);
}
bp->b_vp = (struct vnode *) 0;
- HOLDRELE(vp);
+
+ simple_lock(&vp->v_interlock);
+#ifdef DIAGNOSTIC
+ if (vp->v_holdcnt <= 0)
+ panic("brelvp: holdcnt");
+#endif
+
+ vp->v_holdcnt--;
+
+ /*
+ * If it is on the holdlist and the hold count drops to
+ * zero, move it to the free list.
+ */
+ if ((vp->v_bioflag & VBIOONFREELIST) &&
+ vp->v_holdcnt == 0 && vp->v_usecount == 0) {
+ simple_lock(&vnode_free_list_slock);
+ TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
+ TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
+ simple_unlock(&vnode_free_list_slock);
+ }
+ simple_unlock(&vp->v_interlock);
+}
+
+/*
+ * Replaces the current vnode associated with the buffer, if any
+ * with a new vnode.
+ *
+ * If an output I/O is pending on the buffer, the old vnode is
+ * I/O count is adjusted.
+ *
+ * Ignores vnode buffer queues. Must be called at splbio().
+ */
+void
+buf_replacevnode(bp, newvp)
+ struct buf *bp;
+ struct vnode *newvp;
+{
+ struct vnode *oldvp = bp->b_vp;
+
+ if (oldvp)
+ brelvp(bp);
+
+ if ((bp->b_flags & (B_READ | B_DONE)) == 0) {
+ newvp->v_numoutput++; /* put it on swapdev */
+ vwakeup(oldvp);
+ }
+
+ bgetvp(newvp, bp);
+ bufremvn(bp);
}
/*
- * Reassign a buffer from one vnode to another. Used to assign buffers
- * to the appropriate clean or dirty list and to add newly dirty vnodes
- * to the appropriate filesystem syncer list.
+ * Used to assign buffers to the appropriate clean or dirty list on
+ * the vnode and to add newly dirty vnodes to the appropriate
+ * filesystem syncer list.
*
* Manipulates vnode buffer queues. Must be called at splbio().
*/
void
-reassignbuf(bp, newvp)
+reassignbuf(bp)
register struct buf *bp;
- register struct vnode *newvp;
{
struct buflists *listheadp;
int delay;
+ struct vnode *vp = bp->b_vp;
- if (newvp == NULL) {
+ if (vp == NULL) {
printf("reassignbuf: NULL");
return;
}
@@ -2104,21 +2163,21 @@ reassignbuf(bp, newvp)
* otherwise insert onto list of clean buffers.
*/
if ((bp->b_flags & B_DELWRI) == 0) {
- listheadp = &newvp->v_cleanblkhd;
- if ((newvp->v_flag & VONSYNCLIST) &&
- LIST_FIRST(&newvp->v_dirtyblkhd) == NULL) {
- newvp->v_flag &= ~VONSYNCLIST;
- LIST_REMOVE(newvp, v_synclist);
+ listheadp = &vp->v_cleanblkhd;
+ if ((vp->v_bioflag & VBIOONSYNCLIST) &&
+ LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
+ vp->v_bioflag &= ~VBIOONSYNCLIST;
+ LIST_REMOVE(vp, v_synclist);
}
} else {
- listheadp = &newvp->v_dirtyblkhd;
- if ((newvp->v_flag & VONSYNCLIST) == 0) {
- switch (newvp->v_type) {
+ listheadp = &vp->v_dirtyblkhd;
+ if ((vp->v_bioflag & VBIOONSYNCLIST) == 0) {
+ switch (vp->v_type) {
case VDIR:
delay = syncdelay / 2;
break;
case VBLK:
- if (newvp->v_specmountpoint != NULL) {
+ if (vp->v_specmountpoint != NULL) {
delay = syncdelay / 3;
break;
}
@@ -2126,7 +2185,7 @@ reassignbuf(bp, newvp)
default:
delay = syncdelay;
}
- vn_syncer_add_to_worklist(newvp, delay);
+ vn_syncer_add_to_worklist(vp, delay);
}
}
bufinsvn(bp, listheadp);
diff --git a/sys/kern/vfs_sync.c b/sys/kern/vfs_sync.c
index 1e546662bdf..723a3035559 100644
--- a/sys/kern/vfs_sync.c
+++ b/sys/kern/vfs_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_sync.c,v 1.14 2001/02/23 16:05:53 csapuntz Exp $ */
+/* $OpenBSD: vfs_sync.c,v 1.15 2001/02/24 19:07:09 csapuntz Exp $ */
/*
* Portions of this code are:
@@ -126,7 +126,7 @@ vn_syncer_add_to_worklist(vp, delay)
s = splbio();
- if (vp->v_flag & VONSYNCLIST)
+ if (vp->v_bioflag & VBIOONSYNCLIST)
LIST_REMOVE(vp, v_synclist);
if (delay > syncer_maxdelay - 2)
@@ -134,7 +134,7 @@ vn_syncer_add_to_worklist(vp, delay)
slot = (syncer_delayno + delay) & syncer_mask;
LIST_INSERT_HEAD(&syncer_workitem_pending[slot], vp, v_synclist);
- vp->v_flag |= VONSYNCLIST;
+ vp->v_bioflag |= VBIOONSYNCLIST;
splx(s);
}
diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c
index 234073b5d61..5d6281fc865 100644
--- a/sys/miscfs/specfs/spec_vnops.c
+++ b/sys/miscfs/specfs/spec_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spec_vnops.c,v 1.16 2001/02/23 14:42:39 csapuntz Exp $ */
+/* $OpenBSD: spec_vnops.c,v 1.17 2001/02/24 19:07:10 csapuntz Exp $ */
/* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */
/*
@@ -511,10 +511,8 @@ loop:
goto loop;
}
if (ap->a_waitfor == MNT_WAIT) {
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
- }
+ vwaitforio (vp, 0, "spec_fsync", 0);
+
#ifdef DIAGNOSTIC
if (vp->v_dirtyblkhd.lh_first) {
splx(s);
diff --git a/sys/nfs/nfs_nqlease.c b/sys/nfs/nfs_nqlease.c
index e39557c4867..646c8abd523 100644
--- a/sys/nfs/nfs_nqlease.c
+++ b/sys/nfs/nfs_nqlease.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_nqlease.c,v 1.14 1999/02/06 23:07:40 millert Exp $ */
+/* $OpenBSD: nfs_nqlease.c,v 1.15 2001/02/24 19:07:11 csapuntz Exp $ */
/* $NetBSD: nfs_nqlease.c,v 1.14 1996/02/18 14:06:50 fvdl Exp $ */
/*
@@ -179,7 +179,7 @@ nqsrv_getlease(vp, duration, flags, slp, procp, nam, cachablep, frev, cred)
return (error);
*frev = vattr.va_filerev;
s = splsoftclock();
- tlp = vp->v_lease;
+ tlp = 0;
if ((flags & ND_CHECK) == 0)
nfsstats.srvnqnfs_getleases++;
if (tlp == 0) {
@@ -200,7 +200,6 @@ nqsrv_getlease(vp, duration, flags, slp, procp, nam, cachablep, frev, cred)
fh.fh_fid.fid_len - sizeof (int32_t))) {
/* Found it */
lp->lc_vp = vp;
- vp->v_lease = lp;
tlp = lp;
break;
}
@@ -299,7 +298,6 @@ doreply:
if(!lpp)
panic("nfs_nqlease.c: Phoney lpp");
LIST_INSERT_HEAD(lpp, lp, lc_hash);
- vp->v_lease = lp;
s = splsoftclock();
nqsrv_instimeq(lp, *duration);
splx(s);
@@ -635,13 +633,6 @@ nqnfs_serverd()
} else {
CIRCLEQ_REMOVE(&nqtimerhead, lp, lc_timer);
LIST_REMOVE(lp, lc_hash);
- /*
- * This soft reference may no longer be valid, but
- * no harm done. The worst case is if the vnode was
- * recycled and has another valid lease reference,
- * which is dereferenced prematurely.
- */
- lp->lc_vp->v_lease = (struct nqlease *)0;
lph = &lp->lc_host;
lphnext = lp->lc_morehosts;
olphnext = (struct nqm *)0;
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index a49bb3c8fbe..a4e26fff6ab 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vnops.c,v 1.28 2001/02/23 14:52:51 csapuntz Exp $ */
+/* $OpenBSD: nfs_vnops.c,v 1.29 2001/02/24 19:07:11 csapuntz Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */
/*
@@ -2816,23 +2816,19 @@ loop:
goto again;
}
if (waitfor == MNT_WAIT) {
+ loop2:
s = splbio();
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- error = tsleep((caddr_t)&vp->v_numoutput,
- slpflag | (PRIBIO + 1), "nfsfsync", slptimeo);
- if (error) {
- splx(s);
- if (nfs_sigintr(nmp, (struct nfsreq *)0, p))
+ error = vwaitforio(vp, slpflag, "nfs_fsync", slptimeo);
+ splx(s);
+ if (error) {
+ if (nfs_sigintr(nmp, (struct nfsreq *)0, p))
return (EINTR);
- if (slpflag == PCATCH) {
+ if (slpflag == PCATCH) {
slpflag = 0;
slptimeo = 2 * hz;
- }
- s = splbio();
}
+ goto loop2;
}
- splx(s);
if (vp->v_dirtyblkhd.lh_first && commit) {
#if 0
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 171416a0eb9..7c5e8f69938 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: buf.h,v 1.19 2001/02/24 10:37:09 deraadt Exp $ */
+/* $OpenBSD: buf.h,v 1.20 2001/02/24 19:07:07 csapuntz Exp $ */
/* $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */
/*
@@ -226,9 +226,11 @@ void minphys __P((struct buf *bp));
int physio __P((void (*strategy)(struct buf *), struct buf *bp, dev_t dev,
int flags, void (*minphys)(struct buf *), struct uio *uio));
void brelvp __P((struct buf *));
-void reassignbuf __P((struct buf *, struct vnode *));
+void reassignbuf __P((struct buf *));
void bgetvp __P((struct vnode *, struct buf *));
+void buf_replacevnode __P((struct buf *, struct vnode *));
+
static __inline void
buf_start(struct buf *bp)
{
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index b33a081cd93..500339dbca7 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vnode.h,v 1.28 2001/02/23 14:42:37 csapuntz Exp $ */
+/* $OpenBSD: vnode.h,v 1.29 2001/02/24 19:07:07 csapuntz Exp $ */
/* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */
/*
@@ -90,9 +90,12 @@ struct vnode {
#ifdef UVM
struct uvm_vnode v_uvm; /* uvm data */
#endif
- u_long v_flag; /* vnode flags (see below) */
+ u_int32_t v_flag; /* vnode flags (see below) */
int v_usecount; /* reference count of users */
int v_writecount; /* reference count of writers */
+ u_int32_t v_bioflag; /* flags that can be
+ read/written
+ at interrupt level */
long v_holdcnt; /* page & buffer references */
u_long v_id; /* capability identifier */
struct mount *v_mount; /* ptr to vfs we are in */
@@ -111,7 +114,6 @@ struct vnode {
struct specinfo *vu_specinfo; /* device (VCHR, VBLK) */
struct fifoinfo *vu_fifoinfo; /* fifo (VFIFO) */
} v_un;
- struct nqlease *v_lease; /* Soft reference to lease */
struct simplelock v_interlock; /* lock on usecount and flag */
struct lock *v_vnlock; /* used for non-locking fs's */
@@ -141,12 +143,15 @@ struct vnode {
#define VISTTY 0x0008 /* vnode represents a tty */
#define VXLOCK 0x0100 /* vnode is locked to change underlying type */
#define VXWANT 0x0200 /* process is waiting for vnode */
-#define VBWAIT 0x0400 /* waiting for output to complete */
#define VALIASED 0x0800 /* vnode has an alias */
-#define VDIROP 0x1000 /* LFS: vnode is involved in a directory op */
-#define VONFREELIST 0x2000 /* Vnode is on a free list */
#define VLOCKSWORK 0x4000 /* FS supports locking discipline */
-#define VONSYNCLIST 0x8000 /* Vnode is on syncer worklist */
+
+/*
+ * (v_bioflag) Flags that may be manipulated by interrupt handlers
+ */
+#define VBIOWAIT 0x0001 /* waiting for output to complete */
+#define VBIOONSYNCLIST 0x0002 /* Vnode is on syncer worklist */
+#define VBIOONFREELIST 0x0004 /* Vnode is on a free list */
/*
* Vnode attributes. A field value of VNOVAL represents a field whose value
@@ -233,55 +238,16 @@ extern struct freelst vnode_free_list; /* vnode free list */
extern struct simplelock vnode_free_list_slock;
#ifdef DIAGNOSTIC
-#define HOLDRELE(vp) holdrele(vp)
#define VATTR_NULL(vap) vattr_null(vap)
-#define VHOLD(vp) vhold(vp)
-#define VREF(vp) vref(vp)
+void vattr_null __P((struct vattr *vap));
+
-void holdrele __P((struct vnode *));
-void vhold __P((struct vnode *));
+#define VREF(vp) vref(vp)
void vref __P((struct vnode *));
#else
-#define HOLDRELE(vp) holdrele(vp); /* decrease buf or page ref */
#define VATTR_NULL(vap) (*(vap) = va_null) /* initialize a vattr */
-static __inline void holdrele __P((struct vnode *));
-static __inline void vhold __P((struct vnode *));
static __inline void vref __P((struct vnode *));
-
-static __inline void
-holdrele(vp)
- struct vnode *vp;
-{
- simple_lock(&vp->v_interlock);
- vp->v_holdcnt--;
- if ((vp->v_flag & VONFREELIST) &&
- vp->v_holdcnt == 0 && vp->v_usecount == 0) {
- simple_lock(&vnode_free_list_slock);
- TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
- simple_unlock(&vnode_free_list_slock);
- }
- simple_unlock(&vp->v_interlock);
-}
-
-#define VHOLD(vp) vhold(vp) /* increase buf or page ref */
-static __inline void
-vhold(vp)
- struct vnode *vp;
-{
- simple_lock(&vp->v_interlock);
- if ((vp->v_flag & VONFREELIST) &&
- vp->v_holdcnt == 0 && vp->v_usecount == 0) {
- simple_lock(&vnode_free_list_slock);
- TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
- TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
- simple_unlock(&vnode_free_list_slock);
- }
- vp->v_holdcnt++;
- simple_unlock(&vp->v_interlock);
-}
-
#define VREF(vp) vref(vp) /* increase reference */
static __inline void
vref(vp)
@@ -455,20 +421,18 @@ int getnewvnode __P((enum vtagtype tag, struct mount *mp,
int (**vops) __P((void *)), struct vnode **vpp));
int getvnode __P((struct filedesc *fdp, int fd, struct file **fpp));
void getnewfsid __P((struct mount *, int));
-void vattr_null __P((struct vattr *vap));
int vcount __P((struct vnode *vp));
-void vclean __P((struct vnode *, int, struct proc *));
int vfinddev __P((dev_t, enum vtype, struct vnode **));
void vflushbuf __P((struct vnode *vp, int sync));
int vflush __P((struct mount *mp, struct vnode *vp, int flags));
void vntblinit __P((void));
void vn_initialize_syncerd __P((void));
-void vwakeup __P((struct buf *));
+int vwaitforio __P((struct vnode *, int, char *, int));
+void vwakeup __P((struct vnode *));
void vdevgone __P((int, int, int, enum vtype));
int vget __P((struct vnode *vp, int lockflag, struct proc *p));
void vgone __P((struct vnode *vp));
void vgonel __P((struct vnode *, struct proc *));
-void vgoneall __P((struct vnode *vp));
int vinvalbuf __P((struct vnode *vp, int save, struct ucred *cred,
struct proc *p, int slpflag, int slptimeo));
void vprint __P((char *label, struct vnode *vp));
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 570beca3f30..a5e663a4fb8 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_softdep.c,v 1.13 2001/02/23 14:52:51 csapuntz Exp $ */
+/* $OpenBSD: ffs_softdep.c,v 1.14 2001/02/24 19:07:09 csapuntz Exp $ */
/*
* Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
*
@@ -4796,13 +4796,13 @@ drain_output(vp, islocked)
struct vnode *vp;
int islocked;
{
-
+
if (!islocked)
ACQUIRE_LOCK(&lk);
while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
+ vp->v_bioflag |= VBIOWAIT;
FREE_LOCK_INTERLOCKED(&lk);
- tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "drainvp", 0);
+ tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "drain_output", 0);
ACQUIRE_LOCK_INTERLOCKED(&lk);
}
if (!islocked)
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 6f7652873e6..2e2da61ccd7 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vnops.c,v 1.11 2001/02/23 13:59:11 art Exp $ */
+/* $OpenBSD: ffs_vnops.c,v 1.12 2001/02/24 19:07:10 csapuntz Exp $ */
/* $NetBSD: ffs_vnops.c,v 1.7 1996/05/11 18:27:24 mycroft Exp $ */
/*
@@ -296,11 +296,8 @@ loop2:
goto loop2;
}
if (ap->a_waitfor == MNT_WAIT) {
- while (vp->v_numoutput) {
- vp->v_flag |= VBWAIT;
- tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1,
- "ffsfsync", 0);
- }
+ vwaitforio(vp, 0, "ffs_fsync", 0);
+
/*
* Ensure that any filesystem metatdata associated
* with the vnode has been written.
diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c
index dc06fe86710..dddb784ef34 100644
--- a/sys/uvm/uvm_swap.c
+++ b/sys/uvm/uvm_swap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_swap.c,v 1.22 2001/01/29 02:07:49 niklas Exp $ */
+/* $OpenBSD: uvm_swap.c,v 1.23 2001/02/24 19:07:12 csapuntz Exp $ */
/* $NetBSD: uvm_swap.c,v 1.27 1999/03/30 16:07:47 chs Exp $ */
/*
@@ -1323,7 +1323,6 @@ swstrategy(bp)
struct buf *bp;
{
struct swapdev *sdp;
- struct vnode *vp;
int s, pageno, bn;
UVMHIST_FUNC("swstrategy"); UVMHIST_CALLED(pdhist);
@@ -1372,32 +1371,10 @@ swstrategy(bp)
* on the swapdev (sdp).
*/
s = splbio();
- bp->b_blkno = bn; /* swapdev block number */
- vp = sdp->swd_vp; /* swapdev vnode pointer */
- bp->b_dev = sdp->swd_dev; /* swapdev dev_t */
- VHOLD(vp); /* "hold" swapdev vp for i/o */
+ buf_replacevnode(bp, sdp->swd_vp);
- /*
- * if we are doing a write, we have to redirect the i/o on
- * drum's v_numoutput counter to the swapdevs.
- */
- if ((bp->b_flags & B_READ) == 0) {
- vwakeup(bp); /* kills one 'v_numoutput' on drum */
- vp->v_numoutput++; /* put it on swapdev */
- }
-
- /*
- * dissassocate buffer with /dev/drum vnode
- * [could be null if buf was from physio]
- */
- if (bp->b_vp != NULLVP)
- brelvp(bp);
-
- /*
- * finally plug in swapdev vnode and start I/O
- */
- bp->b_vp = vp;
- splx(s);
+ bp->b_blkno = bn;
+ splx(s);
VOP_STRATEGY(bp);
return;
#ifdef SWAP_TO_FILES
@@ -2089,13 +2066,9 @@ uvm_swap_io(pps, startslot, npages, flags)
bp->b_blkno = startblk;
LIST_INIT(&bp->b_dep);
s = splbio();
- VHOLD(swapdev_vp);
- bp->b_vp = swapdev_vp;
+ bp->b_vp = NULL;
+ buf_replacevnode(bp, swapdev_vp);
splx(s);
- /* XXXCDC: isn't swapdev_vp always a VCHR? */
- /* XXXMRG: probably -- this is obviously something inherited... */
- if (swapdev_vp->v_type == VBLK)
- bp->b_dev = swapdev_vp->v_rdev;
bp->b_bcount = npages << PAGE_SHIFT;
/*
@@ -2105,9 +2078,6 @@ uvm_swap_io(pps, startslot, npages, flags)
if ((bp->b_flags & B_READ) == 0) {
bp->b_dirtyoff = 0;
bp->b_dirtyend = npages << PAGE_SHIFT;
- s = splbio();
- swapdev_vp->v_numoutput++;
- splx(s);
#ifdef UVM_SWAP_ENCRYPT
/* mark the pages in the drum for decryption */
if (swap_encrypt_initalized)
diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c
index 56a72b5c91f..73857085549 100644
--- a/sys/vm/vm_swap.c
+++ b/sys/vm/vm_swap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_swap.c,v 1.12 1999/10/11 18:04:08 deraadt Exp $ */
+/* $OpenBSD: vm_swap.c,v 1.13 2001/02/24 19:07:12 csapuntz Exp $ */
/* $NetBSD: vm_swap.c,v 1.64 1998/11/08 19:45:17 mycroft Exp $ */
/*
@@ -860,7 +860,6 @@ swstrategy(bp)
struct buf *bp;
{
struct swapdev *sdp;
- struct vnode *vp;
daddr_t bn;
bn = bp->b_blkno;
@@ -883,21 +882,10 @@ swstrategy(bp)
default:
panic("swstrategy: vnode type %x", sdp->swd_vp->v_type);
case VBLK:
+ s = splbio();
+ buf_replacevnode(bp, sdp->swd_vp);
bp->b_blkno = bn + ctod(CLSIZE);
- vp = sdp->swd_vp;
- bp->b_dev = sdp->swd_dev;
- VHOLD(vp);
- if ((bp->b_flags & B_READ) == 0) {
- int s = splbio();
- vwakeup(bp);
- vp->v_numoutput++;
- splx(s);
- }
-
- if (bp->b_vp != NULL)
- brelvp(bp);
-
- bp->b_vp = vp;
+ splx(s);
VOP_STRATEGY(bp);
return;
#ifdef SWAP_TO_FILES