9660srv: keep data and metadata separate in the cache with a tag
data on the disk is layed out sequentially and directory information is at the end of the disk. we want to keep data and metadata separated so that reading large sequential files will not evict the directory information from the cache causing long seeks. for that, we tag the clusters (an 8th for metadata, and the rest for data) and getbuf() will only evict clusters of the same tag.
This commit is contained in:
parent
f5688dd6c9
commit
2e85e32886
4 changed files with 21 additions and 10 deletions
|
@ -69,7 +69,7 @@ iattach(Xfile *root)
|
|||
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)
|
||||
|
@ -372,7 +372,7 @@ iread(Xfile *f, char *buf, vlong offset, long count)
|
|||
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;
|
||||
|
@ -499,7 +499,7 @@ getdrec(Xfile *f, void *buf)
|
|||
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;
|
||||
|
@ -754,7 +754,7 @@ getcontin(Xdata *dev, uchar *p, uchar **s)
|
|||
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;
|
||||
|
|
|
@ -31,6 +31,7 @@ struct Ioclust
|
|||
int nbuf;
|
||||
Iobuf* buf;
|
||||
uchar* iobuf;
|
||||
ulong tag; /* cache tag for eviction: 0 = data, 1 = metadata */
|
||||
};
|
||||
|
||||
struct Xdata
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
void chat(char*, ...);
|
||||
void* ealloc(long);
|
||||
void error(char*);
|
||||
Iobuf* getbuf(Xdata*, ulong);
|
||||
Iobuf* getbuf(Xdata*, ulong, ulong);
|
||||
Xdata* getxdata(char*);
|
||||
void iobuf_init(void);
|
||||
void nexterror(void);
|
||||
|
|
|
@ -31,7 +31,7 @@ int nclust = NCLUST;
|
|||
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*);
|
||||
|
||||
|
@ -53,6 +53,16 @@ iobuf_init(void)
|
|||
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)
|
||||
|
@ -87,13 +97,13 @@ purgebuf(Xdata *dev)
|
|||
}
|
||||
|
||||
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++;
|
||||
|
@ -141,13 +151,13 @@ putclust(Ioclust *c)
|
|||
}
|
||||
|
||||
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");
|
||||
|
|
Loading…
Reference in a new issue