1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
4 
5 static int
syncarenaindex(Arena * arena,u64int a0)6 syncarenaindex(Arena *arena, u64int a0)
7 {
8 	int ok;
9 	u32int clump;
10 	u64int a;
11 	ClumpInfo ci;
12 	IAddr ia;
13 	AState as;
14 
15 	if(arena->diskstats.clumps == arena->memstats.clumps)
16 		return 0;
17 
18 	memset(&as, 0, sizeof as);
19 	as.arena = arena;
20 	as.stats = arena->diskstats;
21 
22 	ok = 0;
23 	a = a0 + arena->diskstats.used;
24 	for(clump=arena->diskstats.clumps; clump < arena->memstats.clumps; clump++){
25 		if(readclumpinfo(arena, clump, &ci) < 0){
26 			fprint(2, "%s: clump %d: cannot read clumpinfo\n",
27 				arena->name, clump);
28 			ok = -1;
29 			break;
30 		}
31 
32 		ia.type = ci.type;
33 		ia.size = ci.uncsize;
34 		ia.addr = a;
35 		ia.blocks = (ClumpSize + ci.size + (1 << ABlockLog) - 1) >> ABlockLog;
36 		a += ClumpSize + ci.size;
37 
38 		as.stats.used += ClumpSize + ci.size;
39 		as.stats.uncsize += ia.size;
40 		as.stats.clumps++;
41 		if(ci.uncsize > ci.size)
42 			as.stats.cclumps++;
43 		as.aa = a;
44 		insertscore(ci.score, &ia, IEDirty, &as);
45 	}
46 	flushdcache();
47 	return ok;
48 }
49 
50 int
syncindex(Index * ix)51 syncindex(Index *ix)
52 {
53 	Arena *arena;
54 	int i, e, e1, ok;
55 
56 	ok = 0;
57 	for(i = 0; i < ix->narenas; i++){
58 		trace(TraceProc, "syncindex start %d", i);
59 		arena = ix->arenas[i];
60 		e = syncarena(arena, TWID32, 1, 1);
61 		e1 = e;
62 		e1 &= ~(SyncHeader|SyncCIZero|SyncCIErr);
63 		if(e & SyncHeader)
64 			fprint(2, "arena %s: header is out-of-date\n", arena->name);
65 		if(e1){
66 			fprint(2, "arena %s: %x\n", arena->name, e1);
67 			ok = -1;
68 			continue;
69 		}
70 		flushdcache();
71 
72 		if(arena->memstats.clumps == arena->diskstats.clumps)
73 			continue;
74 
75 		fprint(2, "%T %s: indexing %d clumps...\n",
76 			arena->name,
77 			arena->memstats.clumps - arena->diskstats.clumps);
78 
79 		if(syncarenaindex(arena, ix->amap[i].start) < 0){
80 			fprint(2, "arena %s: syncarenaindex: %r\n", arena->name);
81 			ok = -1;
82 			continue;
83 		}
84 		if(wbarena(arena) < 0){
85 			fprint(2, "arena %s: wbarena: %r\n", arena->name);
86 			ok = -1;
87 			continue;
88 		}
89 		flushdcache();
90 		delaykickicache();
91 	}
92 	return ok;
93 }
94