V4/nsys/dmr/bio.c

Compare this file to the similar file:
Show the results in this format:

#include "/sys/nsys/param.h"
#include "/sys/nsys/user.h"
#include "/sys/nsys/buf.h"
#include "/sys/nsys/conf.h"
#include "/sys/nsys/systm.h"

char	buffers[NBUF][512];
struct	buf	swbuf;

struct	{ int int;};
#define	PS	0177776
#define	JTM	3

bread(dev, blkno)
{
	struct buf *bp;
	register struct buf *rbp;

	rbp = bp = getblk(dev, blkno);
	if (rbp->b_flags&B_DONE)
		return(rbp);
	rbp->b_flags =| B_READ;
	rbp->b_wcount = -256;
	(*bdevsw[dev.d_major].d_strategy)(rbp);
	iowait(bp);
	return(bp);
}

bwrite(bp)
struct buf *bp;
{
	register struct buf *rbp;

	rbp = bp;
	rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
	rbp->b_wcount = -256;
	(*bdevsw[rbp->b_dev.d_major].d_strategy)(rbp);
	if ((bp->b_flags&B_ASYNC) == 0) {
		iowait(bp);
		brelse(bp);
	}
}

bdwrite(bp)
struct buf *bp;
{
	register struct buf *rbp;

	rbp = bp;
	if (rbp->b_dev.d_major == JTM)
		bawrite(rbp);
	else {
		rbp->b_flags =| B_DELWRI | B_DONE;
		brelse(rbp);
	}
}

bawrite(bp)
struct buf *bp;
{
	bp->b_flags =| B_ASYNC;
	bwrite(bp);
}

brelse(bp)
struct buf *bp;
{
	register struct buf *rbp;
	register int sps;

	if (bp->b_flags&B_WANTED)
		wakeup(bp);
	if (bfreelist.b_flags&B_WANTED) {
		bfreelist.b_flags =& ~B_WANTED;
		wakeup(&bfreelist);
	}
	rbp = bp;
	sps = PS->int;
	PS->int =| 0300;
	rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC);
	bfreelist.av_back->av_forw = rbp;
	rbp->av_back = bfreelist.av_back;
	bfreelist.av_back = rbp;
	rbp->av_forw = &bfreelist;
	PS->int = sps;
}

getblk(dev, blkno)
{
	register struct buf *bp;
	struct buf *bp1;
	struct devtab *dp;
	register struct devtab *rdp;
	extern lbolt;

    loop:
	if (dev < 0)
		dp = &bfreelist;
	else {
		dp = &devtab[dev.d_major];
		for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) {
			if (bp->b_blkno!=blkno || bp->b_dev!=dev)
				continue;
			if (bp->b_flags&B_BUSY) {
				bp->b_flags =| B_WANTED;
				sleep(bp, PRIBIO);
				goto loop;
			}
			bp1 = bp;
			notavail(bp);
			return(bp1);
		}
	}
	spl6();
	if (bfreelist.av_forw == bfreelist.av_back) {
		bfreelist.b_flags =| B_WANTED;
		sleep(&bfreelist, PRIBIO);
		spl0();
		goto loop;
	}
	spl0();
	notavail(bp1 = bfreelist.av_forw);
	bp = bp1;
	if (bp->b_flags & B_DELWRI) {
		bp->b_flags =| B_ASYNC;
		bwrite(bp);
		goto loop;
	}
	rdp = dp;
	bp->b_flags = B_BUSY | B_RELOC;
	bp->b_back->b_forw = bp->b_forw;
	bp->b_forw->b_back = bp->b_back;
	bp->b_forw = rdp->b_forw;
	bp->b_back = rdp;
	rdp->b_forw->b_back = bp;
	rdp->b_forw = bp;
	bp->b_dev = dev;
	bp->b_blkno = blkno;
	return(bp);
}

iowait(bp)
struct buf *bp;
{
	spl6();
	while ((bp->b_flags&B_DONE)==0)
		sleep(bp, PRIBIO);
	spl0();
	if (bp->b_flags&B_ERROR)
		u.u_error = EIO;
}

notavail(bp)
struct buf *bp;
{
	register struct buf *rbp;
	register int sps;

	rbp = bp;
	sps = PS->int;
	PS->int =| 0300;
	rbp->av_back->av_forw = rbp->av_forw;
	rbp->av_forw->av_back = rbp->av_back;
	rbp->b_flags =| B_BUSY;
	PS->int = sps;
}

iodone(bp)
struct buf *bp;
{
	register struct buf *rbp;

	rbp = bp;
	rbp->b_flags =| B_DONE;
	if (rbp->b_flags&B_ASYNC)
		brelse(rbp);
	else {
		rbp->b_flags =& ~B_WANTED;
		wakeup(rbp);
	}
}

clrbuf(bp)
int *bp;
{
	register *p, *ep;

	p = bp->b_addr;
	for (ep = p+256; p<ep;)
		*p++ = 0;
}

binit()
{
	register struct buf *bp;
	register struct devtab *dp;
	int i;

	bfreelist.b_forw = bfreelist.b_back =
	    bfreelist.av_forw = bfreelist.av_back = &bfreelist;
	for (i=0; i<NBUF; i++) {
		bp = &buf[i];
		bp->b_dev = -1;
		bp->b_addr = buffers[i];
		bp->b_back = &bfreelist;
		bp->b_forw = bfreelist.b_forw;
		bfreelist.b_forw->b_back = bp;
		bfreelist.b_forw = bp;
		brelse(bp);
	}
	for (dp = devtab; dp < &devtab[NMAJ]; dp++) {
		dp->b_forw = dp;
		dp->b_back = dp;
	}
}

/*
 * Device start routine for disks
 */
#define	IENABLE	0100
#define	WCOM	02
#define	RCOM	04
#define	GO	01
devstart(bp, devloc, devblk)
struct buf *bp;
int *devloc;
{
	register int *dp;
	register struct buf *rbp;
	register int com;

	dp = devloc;
	rbp = bp;
	*dp = devblk;			/* block address */
	*--dp = rbp->b_addr;		/* buffer address */
	*--dp = rbp->b_wcount;		/* word count */
	com = IENABLE|GO | rbp->b_flags&B_XMEM;
	if (rbp->b_flags&B_READ)	/* command + x-mem */
		com =| RCOM;
	else
		com =| WCOM;
	*--dp = com;
}

/*
 * swap I/O
 */
swap(blkno, coreaddr, count, rdflg)
{
	spl6();
	while (swbuf.b_flags&B_BUSY) {
		swbuf.b_flags =| B_WANTED;
		sleep(&swbuf.b_flags, PSWP);
	}
	swbuf.b_flags = B_BUSY | rdflg;
	swbuf.b_dev = SWAPDEV;
	swbuf.b_wcount = - (count<<5);	/* 32 w/block */
	swbuf.b_blkno = blkno;
	swbuf.b_addr = coreaddr<<6;	/* 64 b/block */
	swbuf.b_flags =| (coreaddr>>6)&B_XMEM;
	(*bdevsw[SWAPDEV>>8].d_strategy)(&swbuf);
	spl6();
	while((swbuf.b_flags&B_DONE)==0)
		sleep(&swbuf, PSWP);
	if (swbuf.b_flags&B_WANTED)
		wakeup(&swbuf.b_flags);
	spl0();
	swbuf.b_flags =& ~(B_BUSY|B_WANTED);
	return(swbuf.b_flags&B_ERROR);
}

/*
 * make sure all write-behind blocks
 * on dev (or NODEV for all)
 * are flushed out.
 */
bflush(dev)
{
	struct buf *nbp, *xbp;
	register struct buf *bp;

	spl6();
	for (nbp = bfreelist.av_forw; nbp != &bfreelist; ) {
		bp = nbp;
		nbp = bp->av_forw;
		if (bp->b_flags&B_DELWRI && (dev == -1||dev==bp->b_dev)) {
			bp->b_flags =| B_ASYNC;
			xbp = bp;
			notavail(bp);
			bwrite(xbp);
		}
	}
	spl0();
}