7 #define HIOB 31 /* a prime */
10 static Iotrack hiob[HIOB+1]; /* hash buckets + lru list */
11 static Iotrack iobuf[NIOBUF]; /* the real ones */
13 #define UNLINK(p, nx, pr) ((p)->pr->nx = (p)->nx, (p)->nx->pr = (p)->pr)
15 #define LINK(h, p, nx, pr) ((p)->nx = (h)->nx, (p)->pr = (h), \
16 (h)->nx->pr = (p), (h)->nx = (p))
18 #define HTOFRONT(h, p) ((h)->hnext != (p) && (UNLINK(p,hnext,hprev), LINK(h,p,hnext,hprev)))
20 #define TOFRONT(h, p) ((h)->next != (p) && (UNLINK(p, next, prev), LINK(h,p, next, prev)))
23 getsect(Xfs *xf, vlong addr)
25 return getiosect(xf, addr, 1);
29 getosect(Xfs *xf, vlong addr)
31 return getiosect(xf, addr, 0);
35 getiosect(Xfs *xf, vlong addr, int rflag)
44 toff = addr % Sect2trk;
46 t = getiotrack(xf, taddr);
47 if(rflag && (t->flags&BSTALE)){
59 p->flags = t->flags&BSTALE;
62 p->iobuf = t->tp->buf[toff];
74 if(canmlock(&p->lock))
84 t->flags &= ~(BMOD|BIMM);
91 getiotrack(Xfs *xf, vlong addr)
94 Iotrack *mp = &hiob[HIOB];
97 * chat("iotrack %d,%d...", dev, addr);
99 h = (xf->dev<<24) ^ (long)addr;
108 * look for it in the active list
111 for(p=hp->hnext; p != hp; p=p->hnext){
112 if(p->addr != addr || p->xf != xf)
116 if(p->addr == addr && p->xf == xf)
124 * take oldest unref'd entry
127 for(p=mp->prev; p != mp; p=p->prev)
128 if(p->ref == 0 && canmlock(&p->lock)){
135 fprint(2, "iotrack all ref'd\n");
140 p->flags &= ~(BMOD|BIMM);
159 purgetrack(Iotrack *t)
161 int i, ref = Sect2trk;
164 for(i=0; i<Sect2trk; i++){
170 if(canmlock(&p->lock)){
185 chat("[twrite %lld...", t->addr);
186 if(t->flags & BSTALE){
187 for(ref=0,i=0; i<Sect2trk; i++)
198 if(devwrite(t->xf, t->addr, t->tp->buf, Trksize) < 0){
210 uchar buf[Sect2trk][Sectorsize];
212 for(i=0; i<Sect2trk; i++)
215 chat("[tread %lld+%lld...", t->addr, t->xf->offset);
217 if(devread(t->xf, t->addr, t->tp->buf, Trksize) < 0){
225 if(devread(t->xf, t->addr, buf, Trksize) < 0){
229 for(i=0; i<Sect2trk; i++)
230 if(t->tp->p[i] == 0){
231 memmove(t->tp->buf[i], buf[i], Sectorsize);
244 for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++){
263 for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++){
264 if(!(p->flags & BMOD))
269 p->flags &= ~(BMOD|BIMM);
280 for (mp=&hiob[0]; mp<&hiob[HIOB]; mp++)
281 mp->hprev = mp->hnext = mp;
282 mp->prev = mp->next = mp;
284 for (p=&iobuf[0]; p<&iobuf[NIOBUF]; p++) {
285 p->hprev = p->hnext = p;
286 p->prev = p->next = p;
288 p->tp = sbrk(sizeof(Track));
289 memset(p->tp->p, 0, sizeof p->tp->p);
293 static MLock freelock;
294 static Iosect * freelist;
302 if(p = freelist) /* assign = */
305 p = malloc(sizeof(Iosect));