dp = nil;
haveplan9 = 0;
for(i=VOLDESC;i<VOLDESC+100; i++){ /* +100 for sanity */
- p = getbuf(cd->d, i);
+ p = getbuf(cd->d, i, 1);
v = (Voldesc*)(p->iobuf);
if(memcmp(v->byte, "\01CD001\01", 7) == 0){ /* iso */
if(dirp)
while(count > 0){
if(n > count)
n = count;
- p = getbuf(f->xf->d, addr);
+ p = getbuf(f->xf->d, addr, 0);
memmove(&buf[rcnt], &p->iobuf[o], n);
putbuf(p);
count -= n;
ip->offset += Sectorsize-boff;
continue;
}
- p = getbuf(f->xf->d, addr/Sectorsize);
+ p = getbuf(f->xf->d, addr/Sectorsize, 1);
len = p->iobuf[boff];
if(len >= 34)
break;
off = l32(p+12);
len = l32(p+20);
chat("getcontin %d...", bn);
- b = getbuf(dev, bn);
+ b = getbuf(dev, bn, 1);
if(b == 0){
*s = 0;
return 0;
static Ioclust* iohead;
static Ioclust* iotail;
-static Ioclust* getclust(Xdata*, long);
+static Ioclust* getclust(Xdata*, long, ulong);
static void putclust(Ioclust*);
static void xread(Ioclust*);
for(i=0; i<nclust; i++){
c = (Ioclust*)mem;
mem += sizeof(Ioclust);
+
+ /*
+ * on a iso filesystem, data is usually layed out sequentially
+ * but directory information is at the end of the disk. to avoid
+ * evicting directory information when reading large sequential
+ * files, we keep them tagged in the cache. for now, we use
+ * an 8th of the clusters for meta data.
+ */
+ c->tag = i <= (nclust/8);
+
c->addr = -1;
c->prev = iotail;
if(iotail)
}
static Ioclust*
-getclust(Xdata *dev, long addr)
+getclust(Xdata *dev, long addr, ulong tag)
{
Ioclust *c, *f;
f = nil;
for(c=iohead; c; c=c->next){
- if(!c->busy)
+ if(!c->busy && c->tag == tag)
f = c;
if(c->addr == addr && c->dev == dev){
c->busy++;
}
Iobuf*
-getbuf(Xdata *dev, ulong addr)
+getbuf(Xdata *dev, ulong addr, ulong tag)
{
int off;
Ioclust *c;
off = addr%BUFPERCLUST;
- c = getclust(dev, addr - off);
+ c = getclust(dev, addr - off, tag);
if(c->nbuf < off){
c->busy--;
error("I/O read error");