#include "stdinc.h" #include "dat.h" #include "fns.h" static int syncarenaindex(Arena *arena, u64int a0) { int ok; u32int clump; u64int a; ClumpInfo ci; IAddr ia; AState as; if(arena->diskstats.clumps == arena->memstats.clumps) return 0; memset(&as, 0, sizeof as); as.arena = arena; as.stats = arena->diskstats; ok = 0; 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; } ia.type = ci.type; ia.size = ci.uncsize; ia.addr = a; ia.blocks = (ClumpSize + ci.size + (1 << ABlockLog) - 1) >> ABlockLog; a += ClumpSize + ci.size; 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) { Arena *arena; int i, e, e1, ok; ok = 0; for(i = 0; i < ix->narenas; i++){ trace(TraceProc, "syncindex start %d", i); arena = ix->arenas[i]; e = syncarena(arena, TWID32, 1, 1); e1 = e; e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr); if(e & SyncHeader) fprint(2, "arena %s: header is out-of-date\n", arena->name); if(e1){ fprint(2, "arena %s: %x\n", arena->name, e1); ok = -1; 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); 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; } flushdcache(); delaykickicache(); } return ok; }