1 78a779a3 2008-07-20 rsc #include <u.h>
2 78a779a3 2008-07-20 rsc #include <libc.h>
3 78a779a3 2008-07-20 rsc #include <auth.h>
4 78a779a3 2008-07-20 rsc #include <fcall.h>
5 78a779a3 2008-07-20 rsc #include "dat.h"
6 78a779a3 2008-07-20 rsc #include "fns.h"
9 78a779a3 2008-07-20 rsc * We used to use 100 i/o buffers of size 2kb (Sectorsize).
10 78a779a3 2008-07-20 rsc * Unfortunately, reading 2kb at a time often hopping around
11 78a779a3 2008-07-20 rsc * the disk doesn't let us get near the disk bandwidth.
13 78a779a3 2008-07-20 rsc * Based on a trace of iobuf address accesses taken while
14 78a779a3 2008-07-20 rsc * tarring up a Plan 9 distribution CD, we now use 16 128kb
15 78a779a3 2008-07-20 rsc * buffers. This works for ISO9660 because data is required
16 78a779a3 2008-07-20 rsc * to be laid out contiguously; effectively we're doing agressive
17 fa325e9b 2020-01-10 cross * readahead. Because the buffers are so big and the typical
18 78a779a3 2008-07-20 rsc * disk accesses so concentrated, it's okay that we have so few
21 78a779a3 2008-07-20 rsc * If this is used to access multiple discs at once, it's not clear
22 78a779a3 2008-07-20 rsc * how gracefully the scheme degrades, but I'm not convinced
23 78a779a3 2008-07-20 rsc * it's worth worrying about. -rsc
26 78a779a3 2008-07-20 rsc /* trying a larger value to get greater throughput - geoff */
27 78a779a3 2008-07-20 rsc #define BUFPERCLUST 256 /* sectors/cluster; was 64, 64*Sectorsize = 128kb */
28 78a779a3 2008-07-20 rsc #define NCLUST 16
30 78a779a3 2008-07-20 rsc int nclust = NCLUST;
32 78a779a3 2008-07-20 rsc static Ioclust* iohead;
33 78a779a3 2008-07-20 rsc static Ioclust* iotail;
35 78a779a3 2008-07-20 rsc static Ioclust* getclust(Xdata*, long);
36 78a779a3 2008-07-20 rsc static void putclust(Ioclust*);
37 78a779a3 2008-07-20 rsc static void xread(Ioclust*);
40 78a779a3 2008-07-20 rsc iobuf_init(void)
47 78a779a3 2008-07-20 rsc n = nclust*sizeof(Ioclust) +
48 78a779a3 2008-07-20 rsc nclust*BUFPERCLUST*(sizeof(Iobuf)+Sectorsize);
49 310ae033 2017-01-06 rsc mem = malloc(n);
50 310ae033 2017-01-06 rsc if(mem == (void*)0)
51 78a779a3 2008-07-20 rsc panic(0, "iobuf_init");
52 78a779a3 2008-07-20 rsc memset(mem, 0, n);
54 78a779a3 2008-07-20 rsc for(i=0; i<nclust; i++){
55 78a779a3 2008-07-20 rsc c = (Ioclust*)mem;
56 78a779a3 2008-07-20 rsc mem += sizeof(Ioclust);
57 78a779a3 2008-07-20 rsc c->addr = -1;
58 78a779a3 2008-07-20 rsc c->prev = iotail;
60 78a779a3 2008-07-20 rsc iotail->next = c;
62 78a779a3 2008-07-20 rsc if(iohead == nil)
65 78a779a3 2008-07-20 rsc c->buf = (Iobuf*)mem;
66 78a779a3 2008-07-20 rsc mem += BUFPERCLUST*sizeof(Iobuf);
67 78a779a3 2008-07-20 rsc c->iobuf = mem;
68 78a779a3 2008-07-20 rsc mem += BUFPERCLUST*Sectorsize;
69 78a779a3 2008-07-20 rsc for(j=0; j<BUFPERCLUST; j++){
70 78a779a3 2008-07-20 rsc b = &c->buf[j];
71 78a779a3 2008-07-20 rsc b->clust = c;
72 78a779a3 2008-07-20 rsc b->addr = -1;
73 78a779a3 2008-07-20 rsc b->iobuf = c->iobuf+j*Sectorsize;
79 78a779a3 2008-07-20 rsc purgebuf(Xdata *dev)
83 78a779a3 2008-07-20 rsc for(p=iohead; p!=nil; p=p->next)
84 78a779a3 2008-07-20 rsc if(p->dev == dev){
85 78a779a3 2008-07-20 rsc p->addr = -1;
90 78a779a3 2008-07-20 rsc static Ioclust*
91 78a779a3 2008-07-20 rsc getclust(Xdata *dev, long addr)
93 78a779a3 2008-07-20 rsc Ioclust *c, *f;
96 78a779a3 2008-07-20 rsc for(c=iohead; c; c=c->next){
99 78a779a3 2008-07-20 rsc if(c->addr == addr && c->dev == dev){
105 78a779a3 2008-07-20 rsc if(f == nil)
106 78a779a3 2008-07-20 rsc panic(0, "out of buffers");
108 78a779a3 2008-07-20 rsc f->addr = addr;
109 78a779a3 2008-07-20 rsc f->dev = dev;
111 78a779a3 2008-07-20 rsc if(waserror()){
112 78a779a3 2008-07-20 rsc f->addr = -1; /* stop caching */
113 78a779a3 2008-07-20 rsc putclust(f);
114 78a779a3 2008-07-20 rsc nexterror();
122 78a779a3 2008-07-20 rsc putclust(Ioclust *c)
124 78a779a3 2008-07-20 rsc if(c->busy <= 0)
125 78a779a3 2008-07-20 rsc panic(0, "putbuf");
128 78a779a3 2008-07-20 rsc /* Link onto head for LRU */
129 78a779a3 2008-07-20 rsc if(c == iohead)
131 78a779a3 2008-07-20 rsc c->prev->next = c->next;
134 78a779a3 2008-07-20 rsc c->next->prev = c->prev;
136 78a779a3 2008-07-20 rsc iotail = c->prev;
138 78a779a3 2008-07-20 rsc c->prev = nil;
139 78a779a3 2008-07-20 rsc c->next = iohead;
140 78a779a3 2008-07-20 rsc iohead->prev = c;
145 78a779a3 2008-07-20 rsc getbuf(Xdata *dev, ulong addr)
150 78a779a3 2008-07-20 rsc off = addr%BUFPERCLUST;
151 78a779a3 2008-07-20 rsc c = getclust(dev, addr - off);
152 78a779a3 2008-07-20 rsc if(c->nbuf < off){
154 78a779a3 2008-07-20 rsc error("I/O read error");
156 78a779a3 2008-07-20 rsc return &c->buf[off];
160 78a779a3 2008-07-20 rsc putbuf(Iobuf *b)
162 78a779a3 2008-07-20 rsc putclust(b->clust);
166 78a779a3 2008-07-20 rsc xread(Ioclust *c)
171 78a779a3 2008-07-20 rsc dev = c->dev;
172 78a779a3 2008-07-20 rsc seek(dev->dev, (vlong)c->addr * Sectorsize, 0);
173 78a779a3 2008-07-20 rsc n = readn(dev->dev, c->iobuf, BUFPERCLUST*Sectorsize);
174 78a779a3 2008-07-20 rsc if(n < Sectorsize)
175 78a779a3 2008-07-20 rsc error("I/O read error");
176 78a779a3 2008-07-20 rsc c->nbuf = n/Sectorsize;