diff options
| author | Russ Cox <rsc@swtch.com> | 2007-10-29 14:33:17 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@swtch.com> | 2007-10-29 14:33:17 -0400 |
| commit | 45ac814c8609174199cadb6f1bbb4baf7c12c94a (patch) | |
| tree | 49f4b2120a36b080a0ffe8f9988c21db7b97656c /src/cmd/venti/srv/syncindex0.c | |
| parent | c5a183de108e5685305734d5cf984b58bb0d614a (diff) | |
| download | plan9port-45ac814c8609174199cadb6f1bbb4baf7c12c94a.tar.gz plan9port-45ac814c8609174199cadb6f1bbb4baf7c12c94a.zip | |
venti: fix sync deadlock, add /proc stub
Diffstat (limited to 'src/cmd/venti/srv/syncindex0.c')
| -rw-r--r-- | src/cmd/venti/srv/syncindex0.c | 210 |
1 files changed, 59 insertions, 151 deletions
diff --git a/src/cmd/venti/srv/syncindex0.c b/src/cmd/venti/srv/syncindex0.c index 98f6adf1..be3a2ea0 100644 --- a/src/cmd/venti/srv/syncindex0.c +++ b/src/cmd/venti/srv/syncindex0.c @@ -2,184 +2,92 @@ #include "dat.h" #include "fns.h" -enum +static int +syncarenaindex(Arena *arena, u64int a0) { - ClumpChunks = 32*1024 -}; - -static int missing, wrong; - -/* - * shell sort is plenty good enough - * because we're going to do a bunch of disk i/o's - */ -static void -sortclumpinfo(ClumpInfo *ci, int *s, int n) -{ - int i, j, m, t; - - for(m = (n + 3) / 5; m > 0; m = (m + 1) / 3){ - for(i = n - m; i-- > 0;){ - for(j = i + m; j < n; j += m){ - if(memcmp(ci[s[j - m]].score, ci[s[j]].score, VtScoreSize) <= 0) - break; - t = s[j]; - s[j] = s[j - m]; - s[j - m] = t; - } - } - } -} - -int -syncarenaindex(Index *ix, Arena *arena, u32int clump, u64int a, int fix, int *pflush, int check) -{ - Packet *pack; - IEntry ie; + int ok; + u32int clump; + u64int a; + ClumpInfo ci; IAddr ia; - ClumpInfo *ci, *cis; - u64int *addrs; - int i, n, ok, *s, flush; - - trace(TraceProc, "syncarenaindex enter"); + AState as; + + if(arena->diskstats.clumps == arena->memstats.clumps) + return 0; + + memset(&as, 0, sizeof as); + as.arena = arena; + as.stats = arena->diskstats; - flush = 0; - cis = MKN(ClumpInfo, ClumpChunks); - addrs = MKN(u64int, ClumpChunks); - s = MKN(int, ClumpChunks); ok = 0; - for(; clump < arena->memstats.clumps; clump += n){ - n = ClumpChunks; - if(n > arena->memstats.clumps - clump) - n = arena->memstats.clumps - clump; - n = readclumpinfos(arena, clump, cis, n); - if(n <= 0){ - fprint(2, "arena directory read failed\n"); + a = a0 + arena->diskstats.used; + for(clump=arena->diskstats.clumps; clump < arena->memstats.clumps; clump++){ + if(readclumpinfo(arena, clump, &ci) < 0){ + fprint(2, "%s: clump %d: cannot read clumpinfo\n", + arena->name, clump); ok = -1; break; } - for(i = 0; i < n; i++){ - addrs[i] = a; - a += cis[i].size + ClumpSize; - s[i] = i; - } - - sortclumpinfo(cis, s, n); + ia.type = ci.type; + ia.size = ci.uncsize; + ia.addr = a; + ia.blocks = (ClumpSize + ci.size + (1 << ABlockLog) - 1) >> ABlockLog; + a += ClumpSize + ci.size; - for(i = 0; i < n; i++){ - ci = &cis[s[i]]; - ia.type = ci->type; - ia.size = ci->uncsize; - ia.addr = addrs[s[i]]; - ia.blocks = (ci->size + ClumpSize + (1 << ABlockLog) - 1) >> ABlockLog; - - if(!check) - goto Add; - if(loadientry(ix, ci->score, ci->type, &ie) < 0){ - trace(TraceProc, "syncarenaindex missing block %V.%d", ci->score, ci->type); - missing++; - if(0) fprint(2, "missing block type=%d score=%V\n", ci->type, ci->score); - }else if(iaddrcmp(&ia, &ie.ia) != 0){ - trace(TraceProc, "syncarenaindex mismatched entry"); - fprint(2, "\nmismatched index entry and clump at %d\n", clump + i); - fprint(2, "\tclump: type=%d size=%d blocks=%d addr=%lld\n", ia.type, ia.size, ia.blocks, ia.addr); - fprint(2, "\tindex: type=%d size=%d block=%d addr=%lld\n", ie.ia.type, ie.ia.size, ie.ia.blocks, ie.ia.addr); - pack = readlump(ie.score, ie.ia.type, ie.ia.size, nil); - packetfree(pack); - if(pack != nil){ - fprint(2, "duplicated lump\n"); - continue; - } - wrong++; - }else - continue; - Add: - if(!fix){ - ok = -1; - continue; - } - flush = 1; - trace(TraceProc, "syncarenaindex insert %V", ci->score); - insertscore(ci->score, &ia, IEDirty); - } - - if(0 && clump / 1000 != (clump + n) / 1000) - fprint(2, "."); - } - free(cis); - free(addrs); - free(s); - if(flush){ - flushdcache(); - *pflush = 1; + as.stats.used += ClumpSize + ci.size; + as.stats.uncsize += ia.size; + as.stats.clumps++; + if(ci.uncsize > ci.size) + as.stats.cclumps++; + as.aa = a; + insertscore(ci.score, &ia, IEDirty, &as); } + flushdcache(); return ok; } int -syncindex(Index *ix, int fix, int mustflush, int check) +syncindex(Index *ix) { Arena *arena; - AState as; - u64int a; - int i, e, e1, ok, ok1, flush; + int i, e, e1, ok; ok = 0; - flush = 0; for(i = 0; i < ix->narenas; i++){ trace(TraceProc, "syncindex start %d", i); arena = ix->arenas[i]; - /* - * Syncarena will scan through the arena looking for blocks - * that have been forgotten. It will update arena->memstats.used, - * so save the currenct copy as the place to start the - * syncarenaindex scan. - */ - a = arena->memstats.used; - e = syncarena(arena, ix->amap[i].start, TWID32, fix, fix); + e = syncarena(arena, TWID32, 1, 1); e1 = e; - if(fix) - e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr); - if(e1 == SyncHeader) + e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr); + if(e & SyncHeader) fprint(2, "arena %s: header is out-of-date\n", arena->name); - if(e1) + if(e1){ + fprint(2, "arena %s: %x\n", arena->name, e1); ok = -1; - else{ - /* - * use diskstats not memstats here, because diskstats - * is what has been indexed; memstats is what has - * made it to disk (confusing names). - */ - ok1 = syncarenaindex(ix, arena, - arena->diskstats.clumps, - ix->amap[i].start + arena->diskstats.used, - fix, &flush, check); - if(ok1 < 0) - fprint(2, "syncarenaindex: %r\n"); - if(fix && ok1==0 && (e & SyncHeader) && wbarena(arena) < 0) - fprint(2, "arena=%s header write failed: %r\n", arena->name); - ok |= ok1; + continue; + } + flushdcache(); + + if(arena->memstats.clumps == arena->diskstats.clumps) + continue; + + fprint(2, "%T %s: indexing %d clumps...\n", + arena->name, + arena->memstats.clumps - arena->diskstats.clumps); - as.arena = arena; - as.aa = ix->amap[i].start + arena->memstats.used; - as.stats = arena->memstats; - setdcachestate(&as); + if(syncarenaindex(arena, ix->amap[i].start) < 0){ + fprint(2, "arena %s: syncarenaindex: %r\n", arena->name); + ok = -1; + continue; + } + if(wbarena(arena) < 0){ + fprint(2, "arena %s: wbarena: %r\n", arena->name); + ok = -1; + continue; } - } - if(missing || wrong) - fprint(2, "syncindex: %d missing entries, %d wrong entries (flush=%d)\n", missing, wrong, flush); - if(fix && wbindex(ix) < 0){ - fprint(2, "can't write back index header for %s: %r\n", ix->name); - return -1; - } - if(fix && flush){ flushdcache(); - if(mustflush){ - flushicache(); - flushdcache(); - }else - kickicache(); + delaykickicache(); } return ok; } |
