9 * We used to use 100 i/o buffers of size 2kb (Sectorsize).
10 * Unfortunately, reading 2kb at a time often hopping around
11 * the disk doesn't let us get near the disk bandwidth.
13 * Based on a trace of iobuf address accesses taken while
14 * tarring up a Plan 9 distribution CD, we now use 16 128kb
15 * buffers. This works for ISO9660 because data is required
16 * to be laid out contiguously; effectively we're doing agressive
17 * readahead. Because the buffers are so big and the typical
18 * disk accesses so concentrated, it's okay that we have so few
21 * If this is used to access multiple discs at once, it's not clear
22 * how gracefully the scheme degrades, but I'm not convinced
23 * it's worth worrying about. -rsc
26 /* trying a larger value to get greater throughput - geoff */
27 #define BUFPERCLUST 256 /* sectors/cluster; was 64, 64*Sectorsize = 128kb */
32 static Ioclust* iohead;
33 static Ioclust* iotail;
35 static Ioclust* getclust(Xdata*, long);
36 static void putclust(Ioclust*);
37 static void xread(Ioclust*);
47 n = nclust*sizeof(Ioclust) +
48 nclust*BUFPERCLUST*(sizeof(Iobuf)+Sectorsize);
51 panic(0, "iobuf_init");
54 for(i=0; i<nclust; i++){
56 mem += sizeof(Ioclust);
66 mem += BUFPERCLUST*sizeof(Iobuf);
68 mem += BUFPERCLUST*Sectorsize;
69 for(j=0; j<BUFPERCLUST; j++){
73 b->iobuf = c->iobuf+j*Sectorsize;
83 for(p=iohead; p!=nil; p=p->next)
91 getclust(Xdata *dev, long addr)
96 for(c=iohead; c; c=c->next){
99 if(c->addr == addr && c->dev == dev){
106 panic(0, "out of buffers");
112 f->addr = -1; /* stop caching */
128 /* Link onto head for LRU */
131 c->prev->next = c->next;
134 c->next->prev = c->prev;
145 getbuf(Xdata *dev, ulong addr)
150 off = addr%BUFPERCLUST;
151 c = getclust(dev, addr - off);
154 error("I/O read error");
172 seek(dev->dev, (vlong)c->addr * Sectorsize, 0);
173 n = readn(dev->dev, c->iobuf, BUFPERCLUST*Sectorsize);
175 error("I/O read error");
176 c->nbuf = n/Sectorsize;