/*
* if we already have a buffer for this bno, use it
*/
for(b = bc->bb; b < &bc->bb[Nbcache]; b++)
if(b->inuse && b->bno==bno)
goto out;
/*
* get least recently used block
*/
b = (Bbuf*)bc->lnext;
out:
/*
* if dirty, write it out
*/
if(b->dirty)
if(bcwrite(bc, b) < 0)
warning("writing dirty page");
lruref(bc, b);
return b;
}
/*
* allocate a buffer block for a block. it's guaranteed to be there till
* the next Nbcache bcread's.
*/
Bbuf *
bcalloc(Bcache *bc, ulong bno)
{
Bbuf *b;
/*
* read a block into a buffer cache. it's guaranteed to be there till
* the next Nbcache bcread's.
*/
Bbuf *
bcread(Bcache *bc, ulong bno)
{
Bbuf *b;
b = bcfind(bc, bno);
bno &= ~Indbno;
if(b->bno!=bno || !b->inuse)
/*
* read in the one we really want
*/
if(bread(bc, bno, b->data) < 0){
b->inuse = 0;
return 0;
}
b->bno = bno;
b->inuse = 1;
return b;
}
/*
* mark a page dirty, if it's already dirty force a write
*
* N.B: ordering is important.
*/
void
bcmark(Bcache *bc, Bbuf *b)
{
lruref(bc, b);