diff options
-rw-r--r-- | sys/kern/spec_vnops.c | 8 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 18 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 245 | ||||
-rw-r--r-- | sys/kern/vfs_sync.c | 6 | ||||
-rw-r--r-- | sys/miscfs/specfs/spec_vnops.c | 8 | ||||
-rw-r--r-- | sys/nfs/nfs_nqlease.c | 13 | ||||
-rw-r--r-- | sys/nfs/nfs_vnops.c | 20 | ||||
-rw-r--r-- | sys/sys/buf.h | 6 | ||||
-rw-r--r-- | sys/sys/vnode.h | 70 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 8 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 9 | ||||
-rw-r--r-- | sys/uvm/uvm_swap.c | 42 | ||||
-rw-r--r-- | sys/vm/vm_swap.c | 20 |
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 |