mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-11 17:04:19 +01:00
Reviewed by: Many at differnt times in differnt parts,
including alan, john, me, luoqi, and kirk Submitted by: Matt Dillon <dillon@frebsd.org> This change implements a relatively sophisticated fix to getnewbuf(). There were two problems with getnewbuf(). First, the writerecursion can lead to a system stack overflow when you have NFS and/or VN devices in the system. Second, the free/dirty buffer accounting was completely broken. Not only did the nfs routines blow it trying to manually account for the buffer state, but the accounting that was done did not work well with the purpose of their existance: figuring out when getnewbuf() needs to sleep. The meat of the change is to kern/vfs_bio.c. The remaining diffs are all minor except for NFS, which includes both the fixes for bp interaction AND fixes for a 'biodone(): buffer already done' lockup. Sys/buf.h also contains a chaining structure which is not used by this patchset but is used by other patches that are coming soon. This patch deliniated by tags PRE_MAT_GETBUF and POST_MAT_GETBUF. (sorry for the missing T matt)
This commit is contained in:
parent
ed1ff184f3
commit
4ef2094e45
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44679
1086
sys/kern/vfs_bio.c
1086
sys/kern/vfs_bio.c
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
|
||||
* $Id: vfs_cluster.c,v 1.78 1999/01/21 08:29:05 dillon Exp $
|
||||
* $Id: vfs_cluster.c,v 1.79 1999/01/27 21:49:58 dillon Exp $
|
||||
*/
|
||||
|
||||
#include "opt_debug_cluster.h"
|
||||
@ -778,8 +778,8 @@ cluster_wbuild(vp, size, start_lbn, len)
|
||||
bp->b_bufsize += size;
|
||||
|
||||
s = splbio();
|
||||
--numdirtybuffers;
|
||||
tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
|
||||
bundirty(tbp);
|
||||
tbp->b_flags &= ~(B_READ | B_DONE | B_ERROR);
|
||||
tbp->b_flags |= B_ASYNC;
|
||||
reassignbuf(tbp, tbp->b_vp); /* put on clean list */
|
||||
++tbp->b_vp->v_numoutput;
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
|
||||
* $Id: vfs_subr.c,v 1.187 1999/02/19 17:36:58 dillon Exp $
|
||||
* $Id: vfs_subr.c,v 1.188 1999/02/25 05:22:29 dillon Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -901,7 +901,7 @@ vn_syncer_add_to_worklist(struct vnode *vp, int delay)
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static struct proc *updateproc;
|
||||
struct proc *updateproc;
|
||||
static void sched_sync __P((void));
|
||||
static const struct kproc_desc up_kp = {
|
||||
"syncer",
|
||||
@ -937,11 +937,19 @@ sched_sync(void)
|
||||
splx(s);
|
||||
|
||||
while ((vp = LIST_FIRST(slp)) != NULL) {
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
if (VOP_ISLOCKED(vp) == 0) {
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
}
|
||||
s = splbio();
|
||||
if (LIST_FIRST(slp) == vp) {
|
||||
/*
|
||||
* Note: v_tag VT_VFS vps can remain on the
|
||||
* worklist too with no dirty blocks, but
|
||||
* since sync_fsync() moves it to a different
|
||||
* slot we are safe.
|
||||
*/
|
||||
if (TAILQ_EMPTY(&vp->v_dirtyblkhd) &&
|
||||
vp->v_type != VBLK)
|
||||
panic("sched_sync: fsync failed vp %p tag %d", vp, vp->v_tag);
|
||||
@ -1063,7 +1071,6 @@ reassignbuf(bp, newvp)
|
||||
register struct vnode *newvp;
|
||||
{
|
||||
struct buflists *listheadp;
|
||||
struct vnode *oldvp;
|
||||
int delay;
|
||||
int s;
|
||||
|
||||
@ -1086,14 +1093,16 @@ reassignbuf(bp, newvp)
|
||||
* Delete from old vnode list, if on one.
|
||||
*/
|
||||
if (bp->b_xflags & (B_VNDIRTY|B_VNCLEAN)) {
|
||||
oldvp = bp->b_vp;
|
||||
if (bp->b_xflags & B_VNDIRTY)
|
||||
listheadp = &oldvp->v_dirtyblkhd;
|
||||
listheadp = &bp->b_vp->v_dirtyblkhd;
|
||||
else
|
||||
listheadp = &oldvp->v_cleanblkhd;
|
||||
listheadp = &bp->b_vp->v_cleanblkhd;
|
||||
TAILQ_REMOVE(listheadp, bp, b_vnbufs);
|
||||
bp->b_xflags &= ~(B_VNDIRTY|B_VNCLEAN);
|
||||
vdrop(oldvp);
|
||||
if (bp->b_vp != newvp) {
|
||||
vdrop(bp->b_vp);
|
||||
bp->b_vp = NULL; /* for clarification */
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If dirty, put on list of dirty buffers; otherwise insert onto list
|
||||
@ -1145,8 +1154,10 @@ reassignbuf(bp, newvp)
|
||||
LIST_REMOVE(newvp, v_synclist);
|
||||
}
|
||||
}
|
||||
bp->b_vp = newvp;
|
||||
vhold(bp->b_vp);
|
||||
if (bp->b_vp != newvp) {
|
||||
bp->b_vp = newvp;
|
||||
vhold(bp->b_vp);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
|
||||
* $Id: vfs_subr.c,v 1.187 1999/02/19 17:36:58 dillon Exp $
|
||||
* $Id: vfs_subr.c,v 1.188 1999/02/25 05:22:29 dillon Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -901,7 +901,7 @@ vn_syncer_add_to_worklist(struct vnode *vp, int delay)
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static struct proc *updateproc;
|
||||
struct proc *updateproc;
|
||||
static void sched_sync __P((void));
|
||||
static const struct kproc_desc up_kp = {
|
||||
"syncer",
|
||||
@ -937,11 +937,19 @@ sched_sync(void)
|
||||
splx(s);
|
||||
|
||||
while ((vp = LIST_FIRST(slp)) != NULL) {
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
if (VOP_ISLOCKED(vp) == 0) {
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
(void) VOP_FSYNC(vp, p->p_ucred, MNT_LAZY, p);
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
}
|
||||
s = splbio();
|
||||
if (LIST_FIRST(slp) == vp) {
|
||||
/*
|
||||
* Note: v_tag VT_VFS vps can remain on the
|
||||
* worklist too with no dirty blocks, but
|
||||
* since sync_fsync() moves it to a different
|
||||
* slot we are safe.
|
||||
*/
|
||||
if (TAILQ_EMPTY(&vp->v_dirtyblkhd) &&
|
||||
vp->v_type != VBLK)
|
||||
panic("sched_sync: fsync failed vp %p tag %d", vp, vp->v_tag);
|
||||
@ -1063,7 +1071,6 @@ reassignbuf(bp, newvp)
|
||||
register struct vnode *newvp;
|
||||
{
|
||||
struct buflists *listheadp;
|
||||
struct vnode *oldvp;
|
||||
int delay;
|
||||
int s;
|
||||
|
||||
@ -1086,14 +1093,16 @@ reassignbuf(bp, newvp)
|
||||
* Delete from old vnode list, if on one.
|
||||
*/
|
||||
if (bp->b_xflags & (B_VNDIRTY|B_VNCLEAN)) {
|
||||
oldvp = bp->b_vp;
|
||||
if (bp->b_xflags & B_VNDIRTY)
|
||||
listheadp = &oldvp->v_dirtyblkhd;
|
||||
listheadp = &bp->b_vp->v_dirtyblkhd;
|
||||
else
|
||||
listheadp = &oldvp->v_cleanblkhd;
|
||||
listheadp = &bp->b_vp->v_cleanblkhd;
|
||||
TAILQ_REMOVE(listheadp, bp, b_vnbufs);
|
||||
bp->b_xflags &= ~(B_VNDIRTY|B_VNCLEAN);
|
||||
vdrop(oldvp);
|
||||
if (bp->b_vp != newvp) {
|
||||
vdrop(bp->b_vp);
|
||||
bp->b_vp = NULL; /* for clarification */
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If dirty, put on list of dirty buffers; otherwise insert onto list
|
||||
@ -1145,8 +1154,10 @@ reassignbuf(bp, newvp)
|
||||
LIST_REMOVE(newvp, v_synclist);
|
||||
}
|
||||
}
|
||||
bp->b_vp = newvp;
|
||||
vhold(bp->b_vp);
|
||||
if (bp->b_vp != newvp) {
|
||||
bp->b_vp = newvp;
|
||||
vhold(bp->b_vp);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
|
||||
* $Id: nfs_bio.c,v 1.65 1998/12/14 17:51:30 dt Exp $
|
||||
* $Id: nfs_bio.c,v 1.66 1999/01/21 08:29:07 dillon Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -418,6 +418,7 @@ nfs_bioread(vp, uio, ioflag, cred, getpages)
|
||||
return (EINTR);
|
||||
if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
|
||||
rabp->b_flags |= (B_READ | B_ASYNC);
|
||||
rabp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(rabp, 0);
|
||||
if (nfs_asyncio(rabp, cred)) {
|
||||
rabp->b_flags |= B_INVAL|B_ERROR;
|
||||
@ -513,6 +514,7 @@ again:
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_CACHE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(bp, 0);
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error) {
|
||||
@ -537,6 +539,7 @@ again:
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_CACHE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(bp, 0);
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error) {
|
||||
@ -560,6 +563,7 @@ again:
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_DONE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(bp, 0);
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error == 0 && (bp->b_flags & B_INVAL))
|
||||
@ -591,6 +595,7 @@ again:
|
||||
if (rabp) {
|
||||
if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
|
||||
rabp->b_flags |= (B_READ | B_ASYNC);
|
||||
rabp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(rabp, 0);
|
||||
if (nfs_asyncio(rabp, cred)) {
|
||||
rabp->b_flags |= B_INVAL|B_ERROR;
|
||||
@ -840,6 +845,12 @@ again:
|
||||
bp->b_dirtyoff = on;
|
||||
bp->b_dirtyend = on + n;
|
||||
}
|
||||
/*
|
||||
* To avoid code complexity, we may have to throw away
|
||||
* previously valid ranges when merging the new dirty range
|
||||
* into the valid range. As long as we do not *ADD* an
|
||||
* invalid valid range, we are ok.
|
||||
*/
|
||||
if (bp->b_validend == 0 || bp->b_validend < bp->b_dirtyoff ||
|
||||
bp->b_validoff > bp->b_dirtyend) {
|
||||
bp->b_validoff = bp->b_dirtyoff;
|
||||
@ -1004,7 +1015,7 @@ nfs_asyncio(bp, cred)
|
||||
|
||||
if (nfs_numasync == 0)
|
||||
return (EIO);
|
||||
|
||||
|
||||
nmp = VFSTONFS(bp->b_vp->v_mount);
|
||||
again:
|
||||
if (nmp->nm_flag & NFSMNT_INT)
|
||||
@ -1109,12 +1120,12 @@ again:
|
||||
*/
|
||||
int
|
||||
nfs_doio(bp, cr, p)
|
||||
register struct buf *bp;
|
||||
struct buf *bp;
|
||||
struct ucred *cr;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct uio *uiop;
|
||||
register struct vnode *vp;
|
||||
struct uio *uiop;
|
||||
struct vnode *vp;
|
||||
struct nfsnode *np;
|
||||
struct nfsmount *nmp;
|
||||
int error = 0, diff, len, iomode, must_commit = 0;
|
||||
@ -1130,6 +1141,8 @@ nfs_doio(bp, cr, p)
|
||||
uiop->uio_segflg = UIO_SYSSPACE;
|
||||
uiop->uio_procp = p;
|
||||
|
||||
KASSERT(!(bp->b_flags & B_DONE), ("nfs_doio: bp %p already marked done", bp));
|
||||
|
||||
/*
|
||||
* Historically, paging was done with physio, but no more.
|
||||
*/
|
||||
@ -1236,10 +1249,12 @@ nfs_doio(bp, cr, p)
|
||||
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
|
||||
uiop->uio_rw = UIO_WRITE;
|
||||
nfsstats.write_bios++;
|
||||
|
||||
if ((bp->b_flags & (B_ASYNC | B_NEEDCOMMIT | B_NOCACHE | B_CLUSTER)) == B_ASYNC)
|
||||
iomode = NFSV3WRITE_UNSTABLE;
|
||||
else
|
||||
iomode = NFSV3WRITE_FILESYNC;
|
||||
|
||||
bp->b_flags |= B_WRITEINPROG;
|
||||
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
|
||||
if (!error && iomode == NFSV3WRITE_UNSTABLE) {
|
||||
@ -1247,8 +1262,9 @@ nfs_doio(bp, cr, p)
|
||||
if (bp->b_dirtyoff == 0
|
||||
&& bp->b_dirtyend == bp->b_bufsize)
|
||||
bp->b_flags |= B_CLUSTEROK;
|
||||
} else
|
||||
} else {
|
||||
bp->b_flags &= ~B_NEEDCOMMIT;
|
||||
}
|
||||
bp->b_flags &= ~B_WRITEINPROG;
|
||||
|
||||
/*
|
||||
@ -1265,31 +1281,30 @@ nfs_doio(bp, cr, p)
|
||||
* the B_DELWRI and B_NEEDCOMMIT flags.
|
||||
*
|
||||
* If the buffer is marked B_PAGING, it does not reside on
|
||||
* the vp's paging queues so we do not ( and cannot ) reassign
|
||||
* it. XXX numdirtybuffers should be integrated into
|
||||
* reassignbuf() call.
|
||||
* the vp's paging queues so we cannot call bdirty(). The
|
||||
* bp in this case is not an NFS cache block so we should
|
||||
* be safe. XXX
|
||||
*/
|
||||
if (error == EINTR
|
||||
|| (!error && (bp->b_flags & B_NEEDCOMMIT))) {
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
bp->b_flags &= ~(B_INVAL|B_NOCACHE);
|
||||
if ((bp->b_flags & B_PAGING) == 0) {
|
||||
++numdirtybuffers;
|
||||
bp->b_flags |= B_DELWRI;
|
||||
s = splbio();
|
||||
reassignbuf(bp, vp);
|
||||
splx(s);
|
||||
bdirty(bp);
|
||||
bp->b_flags &= ~B_DONE;
|
||||
}
|
||||
if ((bp->b_flags & B_ASYNC) == 0)
|
||||
bp->b_flags |= B_EINTR;
|
||||
splx(s);
|
||||
} else {
|
||||
if (error) {
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = np->n_error = error;
|
||||
np->n_flag |= NWRITEERR;
|
||||
}
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
if (error) {
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = np->n_error = error;
|
||||
np->n_flag |= NWRITEERR;
|
||||
}
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
}
|
||||
} else {
|
||||
bp->b_resid = 0;
|
||||
@ -1299,7 +1314,7 @@ nfs_doio(bp, cr, p)
|
||||
}
|
||||
bp->b_resid = uiop->uio_resid;
|
||||
if (must_commit)
|
||||
nfs_clearcommit(vp->v_mount);
|
||||
nfs_clearcommit(vp->v_mount);
|
||||
biodone(bp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
|
||||
* $Id: nfs_vnops.c,v 1.122 1999/02/13 09:47:30 dillon Exp $
|
||||
* $Id: nfs_vnops.c,v 1.123 1999/02/16 10:49:54 dfr Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -2648,6 +2648,9 @@ nfs_strategy(ap)
|
||||
struct proc *p;
|
||||
int error = 0;
|
||||
|
||||
KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
|
||||
KASSERT((bp->b_flags & B_BUSY), ("nfs_strategy: buffer %p not B_BUSY", bp));
|
||||
|
||||
if (bp->b_flags & B_PHYS)
|
||||
panic("nfs physio");
|
||||
|
||||
@ -2797,6 +2800,10 @@ again:
|
||||
/*
|
||||
* Work out if all buffers are using the same cred
|
||||
* so we can deal with them all with one commit.
|
||||
*
|
||||
* NOTE: we are not clearing B_DONE here, so we have
|
||||
* to do it later on in this routine if we intend to
|
||||
* initiate I/O on the bp.
|
||||
*/
|
||||
if (wcred == NULL)
|
||||
wcred = bp->b_wcred;
|
||||
@ -2804,6 +2811,14 @@ again:
|
||||
wcred = NOCRED;
|
||||
bp->b_flags |= (B_BUSY | B_WRITEINPROG);
|
||||
vfs_busy_pages(bp, 1);
|
||||
|
||||
/*
|
||||
* bp is protected by being B_BUSY, but nbp is not
|
||||
* and vfs_busy_pages() may sleep. We have to
|
||||
* recalculate nbp.
|
||||
*/
|
||||
nbp = TAILQ_NEXT(bp, b_vnbufs);
|
||||
|
||||
/*
|
||||
* A list of these buffers is kept so that the
|
||||
* second loop knows which buffers have actually
|
||||
@ -2849,6 +2864,7 @@ again:
|
||||
|
||||
if (retv == NFSERR_STALEWRITEVERF)
|
||||
nfs_clearcommit(vp->v_mount);
|
||||
|
||||
/*
|
||||
* Now, either mark the blocks I/O done or mark the
|
||||
* blocks dirty, depending on whether the commit
|
||||
@ -2858,23 +2874,27 @@ again:
|
||||
bp = bvec[i];
|
||||
bp->b_flags &= ~(B_NEEDCOMMIT | B_WRITEINPROG);
|
||||
if (retv) {
|
||||
vfs_unbusy_pages(bp);
|
||||
brelse(bp);
|
||||
/*
|
||||
* Error, leave B_DELWRI intact
|
||||
*/
|
||||
vfs_unbusy_pages(bp);
|
||||
brelse(bp);
|
||||
} else {
|
||||
s = splbio(); /* XXX check this positionning */
|
||||
vp->v_numoutput++;
|
||||
bp->b_flags |= B_ASYNC;
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
--numdirtybuffers;
|
||||
if (needsbuffer) {
|
||||
vfs_bio_need_satisfy();
|
||||
}
|
||||
}
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI);
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
reassignbuf(bp, vp);
|
||||
splx(s);
|
||||
biodone(bp);
|
||||
/*
|
||||
* Success, remove B_DELWRI ( bundirty() ).
|
||||
*
|
||||
* b_dirtyoff/b_dirtyend seem to be NFS
|
||||
* specific. We should probably move that
|
||||
* into bundirty(). XXX
|
||||
*/
|
||||
s = splbio();
|
||||
vp->v_numoutput++;
|
||||
bp->b_flags |= B_ASYNC;
|
||||
bundirty(bp);
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR);
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
splx(s);
|
||||
biodone(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2999,6 +3019,8 @@ nfs_print(ap)
|
||||
|
||||
/*
|
||||
* Just call nfs_writebp() with the force argument set to 1.
|
||||
*
|
||||
* NOTE: B_DONE may or may not be set in a_bp on call.
|
||||
*/
|
||||
static int
|
||||
nfs_bwrite(ap)
|
||||
@ -3020,26 +3042,24 @@ nfs_writebp(bp, force)
|
||||
int force;
|
||||
{
|
||||
int s;
|
||||
register int oldflags = bp->b_flags, retv = 1;
|
||||
int oldflags = bp->b_flags;
|
||||
int retv = 1;
|
||||
off_t off;
|
||||
|
||||
if(!(bp->b_flags & B_BUSY))
|
||||
panic("bwrite: buffer is not busy???");
|
||||
|
||||
if (bp->b_flags & B_INVAL)
|
||||
bp->b_flags |= B_INVAL | B_NOCACHE;
|
||||
bp->b_flags |= B_NOCACHE;
|
||||
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
--numdirtybuffers;
|
||||
if (needsbuffer)
|
||||
vfs_bio_need_satisfy();
|
||||
}
|
||||
s = splbio(); /* XXX check if needed */
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI);
|
||||
/*
|
||||
* XXX we bundirty() the bp here. Shouldn't we do it later after
|
||||
* the I/O has completed??
|
||||
*/
|
||||
|
||||
if ((oldflags & (B_ASYNC|B_DELWRI)) == (B_ASYNC|B_DELWRI)) {
|
||||
reassignbuf(bp, bp->b_vp);
|
||||
}
|
||||
s = splbio();
|
||||
bundirty(bp);
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR);
|
||||
|
||||
bp->b_vp->v_numoutput++;
|
||||
curproc->p_stats->p_ru.ru_oublock++;
|
||||
@ -3061,8 +3081,9 @@ nfs_writebp(bp, force)
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
bp->b_flags &= ~B_NEEDCOMMIT;
|
||||
biodone(bp);
|
||||
} else if (retv == NFSERR_STALEWRITEVERF)
|
||||
} else if (retv == NFSERR_STALEWRITEVERF) {
|
||||
nfs_clearcommit(bp->b_vp->v_mount);
|
||||
}
|
||||
}
|
||||
if (retv) {
|
||||
if (force)
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
|
||||
* $Id: nfs_bio.c,v 1.65 1998/12/14 17:51:30 dt Exp $
|
||||
* $Id: nfs_bio.c,v 1.66 1999/01/21 08:29:07 dillon Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -418,6 +418,7 @@ nfs_bioread(vp, uio, ioflag, cred, getpages)
|
||||
return (EINTR);
|
||||
if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
|
||||
rabp->b_flags |= (B_READ | B_ASYNC);
|
||||
rabp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(rabp, 0);
|
||||
if (nfs_asyncio(rabp, cred)) {
|
||||
rabp->b_flags |= B_INVAL|B_ERROR;
|
||||
@ -513,6 +514,7 @@ again:
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_CACHE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(bp, 0);
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error) {
|
||||
@ -537,6 +539,7 @@ again:
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_CACHE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(bp, 0);
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error) {
|
||||
@ -560,6 +563,7 @@ again:
|
||||
return (EINTR);
|
||||
if ((bp->b_flags & B_DONE) == 0) {
|
||||
bp->b_flags |= B_READ;
|
||||
bp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(bp, 0);
|
||||
error = nfs_doio(bp, cred, p);
|
||||
if (error == 0 && (bp->b_flags & B_INVAL))
|
||||
@ -591,6 +595,7 @@ again:
|
||||
if (rabp) {
|
||||
if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
|
||||
rabp->b_flags |= (B_READ | B_ASYNC);
|
||||
rabp->b_flags &= ~B_DONE;
|
||||
vfs_busy_pages(rabp, 0);
|
||||
if (nfs_asyncio(rabp, cred)) {
|
||||
rabp->b_flags |= B_INVAL|B_ERROR;
|
||||
@ -840,6 +845,12 @@ again:
|
||||
bp->b_dirtyoff = on;
|
||||
bp->b_dirtyend = on + n;
|
||||
}
|
||||
/*
|
||||
* To avoid code complexity, we may have to throw away
|
||||
* previously valid ranges when merging the new dirty range
|
||||
* into the valid range. As long as we do not *ADD* an
|
||||
* invalid valid range, we are ok.
|
||||
*/
|
||||
if (bp->b_validend == 0 || bp->b_validend < bp->b_dirtyoff ||
|
||||
bp->b_validoff > bp->b_dirtyend) {
|
||||
bp->b_validoff = bp->b_dirtyoff;
|
||||
@ -1004,7 +1015,7 @@ nfs_asyncio(bp, cred)
|
||||
|
||||
if (nfs_numasync == 0)
|
||||
return (EIO);
|
||||
|
||||
|
||||
nmp = VFSTONFS(bp->b_vp->v_mount);
|
||||
again:
|
||||
if (nmp->nm_flag & NFSMNT_INT)
|
||||
@ -1109,12 +1120,12 @@ again:
|
||||
*/
|
||||
int
|
||||
nfs_doio(bp, cr, p)
|
||||
register struct buf *bp;
|
||||
struct buf *bp;
|
||||
struct ucred *cr;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct uio *uiop;
|
||||
register struct vnode *vp;
|
||||
struct uio *uiop;
|
||||
struct vnode *vp;
|
||||
struct nfsnode *np;
|
||||
struct nfsmount *nmp;
|
||||
int error = 0, diff, len, iomode, must_commit = 0;
|
||||
@ -1130,6 +1141,8 @@ nfs_doio(bp, cr, p)
|
||||
uiop->uio_segflg = UIO_SYSSPACE;
|
||||
uiop->uio_procp = p;
|
||||
|
||||
KASSERT(!(bp->b_flags & B_DONE), ("nfs_doio: bp %p already marked done", bp));
|
||||
|
||||
/*
|
||||
* Historically, paging was done with physio, but no more.
|
||||
*/
|
||||
@ -1236,10 +1249,12 @@ nfs_doio(bp, cr, p)
|
||||
io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
|
||||
uiop->uio_rw = UIO_WRITE;
|
||||
nfsstats.write_bios++;
|
||||
|
||||
if ((bp->b_flags & (B_ASYNC | B_NEEDCOMMIT | B_NOCACHE | B_CLUSTER)) == B_ASYNC)
|
||||
iomode = NFSV3WRITE_UNSTABLE;
|
||||
else
|
||||
iomode = NFSV3WRITE_FILESYNC;
|
||||
|
||||
bp->b_flags |= B_WRITEINPROG;
|
||||
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
|
||||
if (!error && iomode == NFSV3WRITE_UNSTABLE) {
|
||||
@ -1247,8 +1262,9 @@ nfs_doio(bp, cr, p)
|
||||
if (bp->b_dirtyoff == 0
|
||||
&& bp->b_dirtyend == bp->b_bufsize)
|
||||
bp->b_flags |= B_CLUSTEROK;
|
||||
} else
|
||||
} else {
|
||||
bp->b_flags &= ~B_NEEDCOMMIT;
|
||||
}
|
||||
bp->b_flags &= ~B_WRITEINPROG;
|
||||
|
||||
/*
|
||||
@ -1265,31 +1281,30 @@ nfs_doio(bp, cr, p)
|
||||
* the B_DELWRI and B_NEEDCOMMIT flags.
|
||||
*
|
||||
* If the buffer is marked B_PAGING, it does not reside on
|
||||
* the vp's paging queues so we do not ( and cannot ) reassign
|
||||
* it. XXX numdirtybuffers should be integrated into
|
||||
* reassignbuf() call.
|
||||
* the vp's paging queues so we cannot call bdirty(). The
|
||||
* bp in this case is not an NFS cache block so we should
|
||||
* be safe. XXX
|
||||
*/
|
||||
if (error == EINTR
|
||||
|| (!error && (bp->b_flags & B_NEEDCOMMIT))) {
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
bp->b_flags &= ~(B_INVAL|B_NOCACHE);
|
||||
if ((bp->b_flags & B_PAGING) == 0) {
|
||||
++numdirtybuffers;
|
||||
bp->b_flags |= B_DELWRI;
|
||||
s = splbio();
|
||||
reassignbuf(bp, vp);
|
||||
splx(s);
|
||||
bdirty(bp);
|
||||
bp->b_flags &= ~B_DONE;
|
||||
}
|
||||
if ((bp->b_flags & B_ASYNC) == 0)
|
||||
bp->b_flags |= B_EINTR;
|
||||
splx(s);
|
||||
} else {
|
||||
if (error) {
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = np->n_error = error;
|
||||
np->n_flag |= NWRITEERR;
|
||||
}
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
if (error) {
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = np->n_error = error;
|
||||
np->n_flag |= NWRITEERR;
|
||||
}
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
}
|
||||
} else {
|
||||
bp->b_resid = 0;
|
||||
@ -1299,7 +1314,7 @@ nfs_doio(bp, cr, p)
|
||||
}
|
||||
bp->b_resid = uiop->uio_resid;
|
||||
if (must_commit)
|
||||
nfs_clearcommit(vp->v_mount);
|
||||
nfs_clearcommit(vp->v_mount);
|
||||
biodone(bp);
|
||||
return (error);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
|
||||
* $Id: nfs_vnops.c,v 1.122 1999/02/13 09:47:30 dillon Exp $
|
||||
* $Id: nfs_vnops.c,v 1.123 1999/02/16 10:49:54 dfr Exp $
|
||||
*/
|
||||
|
||||
|
||||
@ -2648,6 +2648,9 @@ nfs_strategy(ap)
|
||||
struct proc *p;
|
||||
int error = 0;
|
||||
|
||||
KASSERT(!(bp->b_flags & B_DONE), ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
|
||||
KASSERT((bp->b_flags & B_BUSY), ("nfs_strategy: buffer %p not B_BUSY", bp));
|
||||
|
||||
if (bp->b_flags & B_PHYS)
|
||||
panic("nfs physio");
|
||||
|
||||
@ -2797,6 +2800,10 @@ again:
|
||||
/*
|
||||
* Work out if all buffers are using the same cred
|
||||
* so we can deal with them all with one commit.
|
||||
*
|
||||
* NOTE: we are not clearing B_DONE here, so we have
|
||||
* to do it later on in this routine if we intend to
|
||||
* initiate I/O on the bp.
|
||||
*/
|
||||
if (wcred == NULL)
|
||||
wcred = bp->b_wcred;
|
||||
@ -2804,6 +2811,14 @@ again:
|
||||
wcred = NOCRED;
|
||||
bp->b_flags |= (B_BUSY | B_WRITEINPROG);
|
||||
vfs_busy_pages(bp, 1);
|
||||
|
||||
/*
|
||||
* bp is protected by being B_BUSY, but nbp is not
|
||||
* and vfs_busy_pages() may sleep. We have to
|
||||
* recalculate nbp.
|
||||
*/
|
||||
nbp = TAILQ_NEXT(bp, b_vnbufs);
|
||||
|
||||
/*
|
||||
* A list of these buffers is kept so that the
|
||||
* second loop knows which buffers have actually
|
||||
@ -2849,6 +2864,7 @@ again:
|
||||
|
||||
if (retv == NFSERR_STALEWRITEVERF)
|
||||
nfs_clearcommit(vp->v_mount);
|
||||
|
||||
/*
|
||||
* Now, either mark the blocks I/O done or mark the
|
||||
* blocks dirty, depending on whether the commit
|
||||
@ -2858,23 +2874,27 @@ again:
|
||||
bp = bvec[i];
|
||||
bp->b_flags &= ~(B_NEEDCOMMIT | B_WRITEINPROG);
|
||||
if (retv) {
|
||||
vfs_unbusy_pages(bp);
|
||||
brelse(bp);
|
||||
/*
|
||||
* Error, leave B_DELWRI intact
|
||||
*/
|
||||
vfs_unbusy_pages(bp);
|
||||
brelse(bp);
|
||||
} else {
|
||||
s = splbio(); /* XXX check this positionning */
|
||||
vp->v_numoutput++;
|
||||
bp->b_flags |= B_ASYNC;
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
--numdirtybuffers;
|
||||
if (needsbuffer) {
|
||||
vfs_bio_need_satisfy();
|
||||
}
|
||||
}
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI);
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
reassignbuf(bp, vp);
|
||||
splx(s);
|
||||
biodone(bp);
|
||||
/*
|
||||
* Success, remove B_DELWRI ( bundirty() ).
|
||||
*
|
||||
* b_dirtyoff/b_dirtyend seem to be NFS
|
||||
* specific. We should probably move that
|
||||
* into bundirty(). XXX
|
||||
*/
|
||||
s = splbio();
|
||||
vp->v_numoutput++;
|
||||
bp->b_flags |= B_ASYNC;
|
||||
bundirty(bp);
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR);
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
splx(s);
|
||||
biodone(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2999,6 +3019,8 @@ nfs_print(ap)
|
||||
|
||||
/*
|
||||
* Just call nfs_writebp() with the force argument set to 1.
|
||||
*
|
||||
* NOTE: B_DONE may or may not be set in a_bp on call.
|
||||
*/
|
||||
static int
|
||||
nfs_bwrite(ap)
|
||||
@ -3020,26 +3042,24 @@ nfs_writebp(bp, force)
|
||||
int force;
|
||||
{
|
||||
int s;
|
||||
register int oldflags = bp->b_flags, retv = 1;
|
||||
int oldflags = bp->b_flags;
|
||||
int retv = 1;
|
||||
off_t off;
|
||||
|
||||
if(!(bp->b_flags & B_BUSY))
|
||||
panic("bwrite: buffer is not busy???");
|
||||
|
||||
if (bp->b_flags & B_INVAL)
|
||||
bp->b_flags |= B_INVAL | B_NOCACHE;
|
||||
bp->b_flags |= B_NOCACHE;
|
||||
|
||||
if (bp->b_flags & B_DELWRI) {
|
||||
--numdirtybuffers;
|
||||
if (needsbuffer)
|
||||
vfs_bio_need_satisfy();
|
||||
}
|
||||
s = splbio(); /* XXX check if needed */
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI);
|
||||
/*
|
||||
* XXX we bundirty() the bp here. Shouldn't we do it later after
|
||||
* the I/O has completed??
|
||||
*/
|
||||
|
||||
if ((oldflags & (B_ASYNC|B_DELWRI)) == (B_ASYNC|B_DELWRI)) {
|
||||
reassignbuf(bp, bp->b_vp);
|
||||
}
|
||||
s = splbio();
|
||||
bundirty(bp);
|
||||
bp->b_flags &= ~(B_READ|B_DONE|B_ERROR);
|
||||
|
||||
bp->b_vp->v_numoutput++;
|
||||
curproc->p_stats->p_ru.ru_oublock++;
|
||||
@ -3061,8 +3081,9 @@ nfs_writebp(bp, force)
|
||||
bp->b_dirtyoff = bp->b_dirtyend = 0;
|
||||
bp->b_flags &= ~B_NEEDCOMMIT;
|
||||
biodone(bp);
|
||||
} else if (retv == NFSERR_STALEWRITEVERF)
|
||||
} else if (retv == NFSERR_STALEWRITEVERF) {
|
||||
nfs_clearcommit(bp->b_vp->v_mount);
|
||||
}
|
||||
}
|
||||
if (retv) {
|
||||
if (force)
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)buf.h 8.9 (Berkeley) 3/30/95
|
||||
* $Id: buf.h,v 1.63 1999/01/21 13:41:12 peter Exp $
|
||||
* $Id: buf.h,v 1.64 1999/03/02 04:04:28 mckusick Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BUF_H_
|
||||
@ -127,6 +127,10 @@ struct buf {
|
||||
struct vm_page *b_pages[btoc(MAXPHYS)];
|
||||
int b_npages;
|
||||
struct workhead b_dep; /* List of filesystem dependencies. */
|
||||
struct chain_info { /* buffer chaining */
|
||||
struct buf *parent;
|
||||
int count;
|
||||
} b_chain;
|
||||
};
|
||||
|
||||
#define b_spc b_pager.pg_spc
|
||||
@ -184,12 +188,12 @@ struct buf {
|
||||
#define B_RAM 0x10000000 /* Read ahead mark (flag) */
|
||||
#define B_VMIO 0x20000000 /* VMIO flag */
|
||||
#define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */
|
||||
#define B_AVAIL1 0x80000000 /* Available flag */
|
||||
#define B_AUTOCHAINDONE 0x80000000 /* Available flag */
|
||||
|
||||
#define PRINT_BUF_FLAGS "\20\40avail1\37cluster\36vmio\35ram\34ordered" \
|
||||
#define PRINT_BUF_FLAGS "\20\40autochain\37cluster\36vmio\35ram\34ordered" \
|
||||
"\33paging\32xxx\31writeinprog\30wanted\27relbuf\26dirty" \
|
||||
"\25read\24raw\23phys\22clusterok\21malloc\20nocache" \
|
||||
"\17locked\16inval\15avail2\14error\13eintr\12done\11freebuf" \
|
||||
"\17locked\16inval\15scanned\14error\13eintr\12done\11freebuf" \
|
||||
"\10delwri\7call\6cache\5busy\4bad\3async\2needcommit\1age"
|
||||
|
||||
/*
|
||||
@ -315,7 +319,6 @@ extern char *buffers; /* The buffer contents. */
|
||||
extern int bufpages; /* Number of memory pages in the buffer pool. */
|
||||
extern struct buf *swbuf; /* Swap I/O buffer headers. */
|
||||
extern int nswbuf; /* Number of swap I/O buffer headers. */
|
||||
extern int needsbuffer, numdirtybuffers;
|
||||
extern TAILQ_HEAD(swqueue, buf) bswlist;
|
||||
extern TAILQ_HEAD(bqueues, buf) bufqueues[BUFFER_QUEUES];
|
||||
|
||||
@ -331,6 +334,7 @@ int bwrite __P((struct buf *));
|
||||
void bdwrite __P((struct buf *));
|
||||
void bawrite __P((struct buf *));
|
||||
void bdirty __P((struct buf *));
|
||||
void bundirty __P((struct buf *));
|
||||
int bowrite __P((struct buf *));
|
||||
void brelse __P((struct buf *));
|
||||
void bqrelse __P((struct buf *));
|
||||
@ -367,7 +371,6 @@ int allocbuf __P((struct buf *bp, int size));
|
||||
void reassignbuf __P((struct buf *, struct vnode *));
|
||||
void pbreassignbuf __P((struct buf *, struct vnode *));
|
||||
struct buf *trypbuf __P((int *));
|
||||
void vfs_bio_need_satisfy __P((void));
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* !_SYS_BUF_H_ */
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)buf.h 8.9 (Berkeley) 3/30/95
|
||||
* $Id: buf.h,v 1.63 1999/01/21 13:41:12 peter Exp $
|
||||
* $Id: buf.h,v 1.64 1999/03/02 04:04:28 mckusick Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BUF_H_
|
||||
@ -127,6 +127,10 @@ struct buf {
|
||||
struct vm_page *b_pages[btoc(MAXPHYS)];
|
||||
int b_npages;
|
||||
struct workhead b_dep; /* List of filesystem dependencies. */
|
||||
struct chain_info { /* buffer chaining */
|
||||
struct buf *parent;
|
||||
int count;
|
||||
} b_chain;
|
||||
};
|
||||
|
||||
#define b_spc b_pager.pg_spc
|
||||
@ -184,12 +188,12 @@ struct buf {
|
||||
#define B_RAM 0x10000000 /* Read ahead mark (flag) */
|
||||
#define B_VMIO 0x20000000 /* VMIO flag */
|
||||
#define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */
|
||||
#define B_AVAIL1 0x80000000 /* Available flag */
|
||||
#define B_AUTOCHAINDONE 0x80000000 /* Available flag */
|
||||
|
||||
#define PRINT_BUF_FLAGS "\20\40avail1\37cluster\36vmio\35ram\34ordered" \
|
||||
#define PRINT_BUF_FLAGS "\20\40autochain\37cluster\36vmio\35ram\34ordered" \
|
||||
"\33paging\32xxx\31writeinprog\30wanted\27relbuf\26dirty" \
|
||||
"\25read\24raw\23phys\22clusterok\21malloc\20nocache" \
|
||||
"\17locked\16inval\15avail2\14error\13eintr\12done\11freebuf" \
|
||||
"\17locked\16inval\15scanned\14error\13eintr\12done\11freebuf" \
|
||||
"\10delwri\7call\6cache\5busy\4bad\3async\2needcommit\1age"
|
||||
|
||||
/*
|
||||
@ -315,7 +319,6 @@ extern char *buffers; /* The buffer contents. */
|
||||
extern int bufpages; /* Number of memory pages in the buffer pool. */
|
||||
extern struct buf *swbuf; /* Swap I/O buffer headers. */
|
||||
extern int nswbuf; /* Number of swap I/O buffer headers. */
|
||||
extern int needsbuffer, numdirtybuffers;
|
||||
extern TAILQ_HEAD(swqueue, buf) bswlist;
|
||||
extern TAILQ_HEAD(bqueues, buf) bufqueues[BUFFER_QUEUES];
|
||||
|
||||
@ -331,6 +334,7 @@ int bwrite __P((struct buf *));
|
||||
void bdwrite __P((struct buf *));
|
||||
void bawrite __P((struct buf *));
|
||||
void bdirty __P((struct buf *));
|
||||
void bundirty __P((struct buf *));
|
||||
int bowrite __P((struct buf *));
|
||||
void brelse __P((struct buf *));
|
||||
void bqrelse __P((struct buf *));
|
||||
@ -367,7 +371,6 @@ int allocbuf __P((struct buf *bp, int size));
|
||||
void reassignbuf __P((struct buf *, struct vnode *));
|
||||
void pbreassignbuf __P((struct buf *, struct vnode *));
|
||||
struct buf *trypbuf __P((int *));
|
||||
void vfs_bio_need_satisfy __P((void));
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* !_SYS_BUF_H_ */
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)proc.h 8.15 (Berkeley) 5/19/95
|
||||
* $Id: proc.h,v 1.73 1999/03/03 18:15:29 julian Exp $
|
||||
* $Id: proc.h,v 1.74 1999/03/05 16:38:12 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_PROC_H_
|
||||
@ -262,10 +262,11 @@ struct proc {
|
||||
#define P_SWAPINREQ 0x80000 /* Swapin request due to wakeup */
|
||||
|
||||
/* Marked a kernel thread */
|
||||
#define P_FLSINPROG 0x100000 /* dirty buffers flush is in progress */
|
||||
#define P_KTHREADP 0x200000 /* Process is really a kernel thread */
|
||||
|
||||
#define P_NOCLDWAIT 0x400000 /* No zombies if child dies */
|
||||
|
||||
#define P_DEADLKTREAT 0x800000 /* lock aquisition - deadlock treatment */
|
||||
|
||||
/*
|
||||
* MOVE TO ucred.h?
|
||||
@ -336,7 +337,7 @@ extern struct timeval switchtime; /* Uptime at last context switch */
|
||||
LIST_HEAD(proclist, proc);
|
||||
extern struct proclist allproc; /* List of all processes. */
|
||||
extern struct proclist zombproc; /* List of zombie processes. */
|
||||
extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */
|
||||
extern struct proc *initproc, *pageproc, *updateproc; /* Process slots for init, pager. */
|
||||
|
||||
#define NQS 32 /* 32 run queues. */
|
||||
extern struct prochd qs[];
|
||||
|
Loading…
Reference in New Issue
Block a user