/* * walk the fat one level ( n is a current cluster number ). * return the new cluster number or -1 if no more. */ static long fatwalk(Dos *dos, int n) { ulong k, sect; Clustbuf *p; int o; chat("fatwalk %d\n", n); if(n < 2 || n >= dos->fatclusters) return -1; switch(dos->fatbits){ case 12: k = (3*n)/2; break; case 16: k = 2*n; break; case 32: k = 4*n; break; default: return -1; } if(k >= dos->fatsize*dos->sectsize) panic("getfat"); if (dos->sectsize == 0 || dos->clustsize == 0) panic("fatwalk: zero sector or cluster size"); sect = (k/(dos->sectsize*dos->clustsize))*dos->clustsize + dos->fataddr; o = k%(dos->sectsize*dos->clustsize); p = getclust(dos, sect); k = p->iobuf[o++]; if(o >= dos->sectsize*dos->clustsize){ p = getclust(dos, sect+dos->clustsize); o = 0; } k |= p->iobuf[o++]<<8; if(dos->fatbits == 12){ if(n&1) k >>= 4; else k &= 0xfff; if(k >= 0xff8) k = -1; }
Iobuf* getbuf(Xdata *dev, ulong addr, ulong tag) { int off; Ioclust *c; off = addr%BUFPERCLUST; c = getclust(dev, addr - off, tag); if(c->nbuf < off){ c->busy--; error("I/O read error"); } return &c->buf[off]; }