#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include "dat.h"
#include "fns.h"

/*
 * We used to use 100 i/o buffers of size 2kb (Sectorsize).
 * Unfortunately, reading 2kb at a time often hopping around
 * the disk doesn't let us get near the disk bandwidth.
 *
 * Based on a trace of iobuf address accesses taken while
 * tarring up a Plan 9 distribution CD, we now use 16 128kb
 * buffers.  This works for ISO9660 because data is required
 * to be laid out contiguously; effectively we're doing agressive
 * readahead.  Because the buffers are so big and the typical 
 * disk accesses so concentrated, it's okay that we have so few
 * of them.
 *
 * If this is used to access multiple discs at once, it's not clear
 * how gracefully the scheme degrades, but I'm not convinced
 * it's worth worrying about.		-rsc
 */

/* trying a larger value to get greater throughput - geoff */
#define	BUFPERCLUST	256 /* sectors/cluster; was 64, 64*Sectorsize = 128kb */
#define	NCLUST		16

int nclust = NCLUST;

static Ioclust*	iohead;
static Ioclust*	iotail;

static Ioclust*	getclust(Xdata*, long);
static void	putclust(Ioclust*);
static void	xread(Ioclust*);

void
iobuf_init(void)
{
	int i, j, n;
	Ioclust *c;
	Iobuf *b;
	uchar *mem;

	n = nclust*sizeof(Ioclust) +
		nclust*BUFPERCLUST*(sizeof(Iobuf)+Sectorsize);
	mem = sbrk(n);
	if(mem == (void*)-1)
		panic(0, "iobuf_init");
	memset(mem, 0, n);

	for(i=0; i<nclust; i++){
		c = (Ioclust*)mem;
		mem += sizeof(Ioclust);
		c->addr = -1;
		c->prev = iotail;
		if(iotail)
			iotail->next = c;
		iotail = c;
		if(iohead == nil)
			iohead = c;

		c->buf = (Iobuf*)mem;
		mem += BUFPERCLUST*sizeof(Iobuf);
		c->iobuf = mem;
		mem += BUFPERCLUST*Sectorsize;
		for(j=0; j<BUFPERCLUST; j++){
			b = &c->buf[j];
			b->clust = c;
			b->addr = -1;
			b->iobuf = c->iobuf+j*Sectorsize;
		}
	}
}

void
purgebuf(Xdata *dev)
{
	Ioclust *p;

	for(p=iohead; p!=nil; p=p->next)
		if(p->dev == dev){
			p->addr = -1;
			p->busy = 0;
		}
}

static Ioclust*
getclust(Xdata *dev, long addr)
{
	Ioclust *c, *f;

	f = nil;
	for(c=iohead; c; c=c->next){
		if(!c->busy)
			f = c;
		if(c->addr == addr && c->dev == dev){
			c->busy++;
			return c;
		}
	}

	if(f == nil)
		panic(0, "out of buffers");

	f->addr = addr;
	f->dev = dev;
	f->busy++;
	if(waserror()){
		f->addr = -1;	/* stop caching */
		putclust(f);
		nexterror();
	}
	xread(f);
	poperror();
	return f;
}

static void
putclust(Ioclust *c)
{
	if(c->busy <= 0)
		panic(0, "putbuf");
	c->busy--;

	/* Link onto head for LRU */
	if(c == iohead)
		return;
	c->prev->next = c->next;

	if(c->next)
		c->next->prev = c->prev;
	else
		iotail = c->prev;

	c->prev = nil;
	c->next = iohead;
	iohead->prev = c;
	iohead = c;
}

Iobuf*
getbuf(Xdata *dev, ulong addr)
{
	int off;
	Ioclust *c;

	off = addr%BUFPERCLUST;
	c = getclust(dev, addr - off);
	if(c->nbuf < off){
		c->busy--;
		error("I/O read error");
	}
	return &c->buf[off];
}

void
putbuf(Iobuf *b)
{
	putclust(b->clust);
}

static void
xread(Ioclust *c)
{
	int n;
	Xdata *dev;

	dev = c->dev;
	seek(dev->dev, (vlong)c->addr * Sectorsize, 0);
	n = readn(dev->dev, c->iobuf, BUFPERCLUST*Sectorsize);
	if(n < Sectorsize)
		error("I/O read error");
	c->nbuf = n/Sectorsize;
}
