diff options
Diffstat (limited to 'src/cmd/venti/srv/icachewrite.c')
-rw-r--r-- | src/cmd/venti/srv/icachewrite.c | 92 |
1 files changed, 52 insertions, 40 deletions
diff --git a/src/cmd/venti/srv/icachewrite.c b/src/cmd/venti/srv/icachewrite.c index 49344c9f..0805001c 100644 --- a/src/cmd/venti/srv/icachewrite.c +++ b/src/cmd/venti/srv/icachewrite.c @@ -45,6 +45,16 @@ initicachewrite(void) vtproc(delaykickroundproc, &iwrite.round); } +static u64int +ie2diskaddr(Index *ix, ISect *is, IEntry *ie) +{ + u64int bucket, addr; + + bucket = hashbits(ie->score, 32)/ix->div; + addr = is->blockbase + ((bucket - is->start) << is->blocklog); + return addr; +} + static IEntry* nextchunk(Index *ix, ISect *is, IEntry **pie, u64int *paddr, uint *pnbuf) { @@ -55,13 +65,13 @@ nextchunk(Index *ix, ISect *is, IEntry **pie, u64int *paddr, uint *pnbuf) bsize = 1<<is->blocklog; iefirst = *pie; - addr = is->blockbase + ((u64int)(hashbits(iefirst->score, 32) / ix->div - is->start) << is->blocklog); + addr = ie2diskaddr(ix, is, iefirst); nbuf = 0; - for(l=&iefirst->nextdirty; (ie=*l)!=nil; l=&(*l)->nextdirty){ - naddr = is->blockbase + ((u64int)(hashbits(ie->score, 32) / ix->div - is->start) << is->blocklog); + for(l = &iefirst->nextdirty; (ie = *l) != nil; l = &(*l)->nextdirty){ + naddr = ie2diskaddr(ix, is, ie); if(naddr - addr >= Bufsize) break; - nbuf = naddr-addr; + nbuf = naddr - addr; } nbuf += bsize; @@ -75,7 +85,7 @@ nextchunk(Index *ix, ISect *is, IEntry **pie, u64int *paddr, uint *pnbuf) static int icachewritesect(Index *ix, ISect *is, u8int *buf) { - int err, h, bsize, t; + int err, i, werr, h, bsize, t; u32int lo, hi; u64int addr, naddr; uint nbuf, off; @@ -89,29 +99,32 @@ icachewritesect(Index *ix, ISect *is, u8int *buf) else hi = is->stop * ix->div - 1; - trace(TraceProc, "icachewritesect enter %ud %ud %llud", lo, hi, iwrite.as.aa); + trace(TraceProc, "icachewritesect enter %ud %ud %llud", + lo, hi, iwrite.as.aa); iedirty = icachedirty(lo, hi, iwrite.as.aa); iedirty = iesort(iedirty); - bsize = 1<<is->blocklog; + bsize = 1 << is->blocklog; err = 0; while(iedirty){ disksched(); - while((t=icachesleeptime) == SleepForever){ + while((t = icachesleeptime) == SleepForever){ sleep(1000); disksched(); } if(t < minicachesleeptime) t = minicachesleeptime; - sleep(t); + if(t > 0) + sleep(t); trace(TraceProc, "icachewritesect nextchunk"); chunk = nextchunk(ix, is, &iedirty, &addr, &nbuf); - trace(TraceProc, "icachewritesect readpart 0x%llux+0x%ux", addr, nbuf); + trace(TraceProc, "icachewritesect readpart 0x%llux+0x%ux", + addr, nbuf); if(readpart(is->part, addr, buf, nbuf) < 0){ - /* XXX more details here */ - fprint(2, "icachewriteproc readpart: %r\n"); + fprint(2, "%s: part %s addr 0x%llux: icachewritesect " + "readpart: %r\n", argv0, is->part->name, addr); err = -1; continue; } @@ -120,31 +133,34 @@ icachewritesect(Index *ix, ISect *is, u8int *buf) addstat(StatIsectRead, 1); for(l=&chunk; (ie=*l)!=nil; l=&ie->nextdirty){ - again: - naddr = is->blockbase + ((u64int)(hashbits(ie->score, 32) / ix->div - is->start) << is->blocklog); +again: + naddr = ie2diskaddr(ix, is, ie); off = naddr - addr; if(off+bsize > nbuf){ - fprint(2, "whoops! addr=0x%llux nbuf=%ud addr+nbuf=0x%llux naddr=0x%llux\n", - addr, nbuf, addr+nbuf, naddr); + fprint(2, "%s: whoops! addr=0x%llux nbuf=%ud " + "addr+nbuf=0x%llux naddr=0x%llux\n", + argv0, addr, nbuf, addr+nbuf, naddr); assert(off+bsize <= nbuf); } unpackibucket(&ib, buf+off, is->bucketmagic); if(okibucket(&ib, is) < 0){ - fprint(2, "bad bucket XXX\n"); + fprint(2, "%s: bad bucket XXX\n", argv0); goto skipit; } - trace(TraceProc, "icachewritesect add %V at 0x%llux", ie->score, naddr); + trace(TraceProc, "icachewritesect add %V at 0x%llux", + ie->score, naddr); h = bucklook(ie->score, ie->ia.type, ib.data, ib.n); if(h & 1){ h ^= 1; packientry(ie, &ib.data[h]); }else if(ib.n < is->buckmax){ - memmove(&ib.data[h+IEntrySize], &ib.data[h], ib.n*IEntrySize - h); + memmove(&ib.data[h + IEntrySize], &ib.data[h], + ib.n*IEntrySize - h); ib.n++; packientry(ie, &ib.data[h]); }else{ - fprint(2, "bucket overflow XXX\n"); - skipit: + fprint(2, "%s: bucket overflow XXX\n", argv0); +skipit: err = -1; *l = ie->nextdirty; ie = *l; @@ -154,33 +170,29 @@ icachewritesect(Index *ix, ISect *is, u8int *buf) break; } packibucket(&ib, buf+off, is->bucketmagic); - /* XXX - * This is not quite right - it's good that we - * update the cached block (if any) here, but - * since the block doesn't get written until writepart - * below, we also need to make sure that the cache - * doesn't load the stale block before we write it to - * disk below. We could lock the disk cache during - * the writepart, but that's pretty annoying. - * Another possibility would be never to cache - * index partition blocks. The hit rate on those is - * miniscule anyway. - */ - if((b = _getdblock(is->part, naddr, ORDWR, 0)) != nil){ - memmove(b->data, buf+off, bsize); - putdblock(b); - } } diskaccess(1); trace(TraceProc, "icachewritesect writepart", addr, nbuf); - if(writepart(is->part, addr, buf, nbuf) < 0 || flushpart(is->part) < 0){ - /* XXX more details here */ - fprint(2, "icachewriteproc writepart: %r\n"); + werr = 0; + if(writepart(is->part, addr, buf, nbuf) < 0 || flushpart(is->part) < 0) + werr = -1; + + for(i=0; i<nbuf; i+=bsize){ + if((b = _getdblock(is->part, addr+i, ORDWR, 0)) != nil){ + memmove(b->data, buf+i, bsize); + putdblock(b); + } + } + + if(werr < 0){ + fprint(2, "%s: part %s addr 0x%llux: icachewritesect " + "writepart: %r\n", argv0, is->part->name, addr); err = -1; continue; } + addstat(StatIsectWriteBytes, nbuf); addstat(StatIsectWrite, 1); icacheclean(chunk); |