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, long addr)
25 return getiosect(xf, addr, 1);
29 getosect(Xfs *xf, long addr)
31 return getiosect(xf, addr, 0);
35 getiosect(Xfs *xf, long addr, int rflag)
42 toff = addr % Sect2trk;
44 t = getiotrack(xf, taddr);
45 if(rflag && (t->flags&BSTALE)){
57 p->flags = t->flags&BSTALE;
60 p->iobuf = t->tp->buf[toff];
72 if(canmlock(&p->lock))
82 t->flags &= ~(BMOD|BIMM);
89 getiotrack(Xfs *xf, long addr)
92 Iotrack *mp = &hiob[HIOB];
95 * chat("iotrack %d,%d...", dev, addr);
97 h = (xf->dev<<24) ^ addr;
106 * look for it in the active list
109 for(p=hp->hnext; p != hp; p=p->hnext){
110 if(p->addr != addr || p->xf != xf)
114 if(p->addr == addr && p->xf == xf)
122 * take oldest unref'd entry
125 for(p=mp->prev; p != mp; p=p->prev)
126 if(p->ref == 0 && canmlock(&p->lock)){
133 print("iotrack all ref'd\n");
138 p->flags &= ~(BMOD|BIMM);
157 purgetrack(Iotrack *t)
159 int i, ref = Sect2trk;
162 for(i=0; i<Sect2trk; i++){
168 if(canmlock(&p->lock)){
183 chat("[twrite %ld...", t->addr);
184 if(t->flags & BSTALE){
185 for(ref=0,i=0; i<Sect2trk; i++)
196 if(devwrite(t->xf, t->addr, t->tp->buf, Trksize) < 0){
208 uchar buf[Sect2trk][Sectorsize];
210 for(i=0; i<Sect2trk; i++)
213 chat("[tread %ld+%ld...", t->addr, t->xf->offset);
215 if(devread(t->xf, t->addr, t->tp->buf, Trksize) < 0){
223 if(devread(t->xf, t->addr, buf, Trksize) < 0){
227 for(i=0; i<Sect2trk; i++)
228 if(t->tp->p[i] == 0){
229 memmove(t->tp->buf[i], buf[i], Sectorsize);
242 for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++){
261 for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++){
262 if(!(p->flags & BMOD))
267 p->flags &= ~(BMOD|BIMM);
278 for (mp=&hiob[0]; mp<&hiob[HIOB]; mp++)
279 mp->hprev = mp->hnext = mp;
280 mp->prev = mp->next = mp;
282 for (p=&iobuf[0]; p<&iobuf[NIOBUF]; p++) {
283 p->hprev = p->hnext = p;
284 p->prev = p->next = p;
286 p->tp = sbrk(sizeof(Track));
287 memset(p->tp->p, 0, sizeof p->tp->p);
291 static MLock freelock;
292 static Iosect * freelist;
300 if(p = freelist) /* assign = */
303 p = malloc(sizeof(Iosect));