5 static int writeclumphead(Arena *arena, u64int aa, Clump *cl);
6 static int writeclumpmagic(Arena *arena, u64int aa, u32int magic);
9 clumpinfocmp(ClumpInfo *c, ClumpInfo *d)
11 return c->type != d->type
13 || c->uncsize != d->uncsize
14 || scorecmp(c->score, d->score)!=0;
18 * synchronize the clump info directory with
19 * with the clumps actually stored in the arena.
20 * the directory should be at least as up to date
21 * as the arena's trailer.
23 * checks/updates at most n clumps.
25 * returns 0 if ok, flags if error occurred
28 syncarena(Arena *arena, u64int start, u32int n, int zok, int fix)
33 static ClumpInfo zci = { .type = -1 };
34 u8int score[VtScoreSize];
35 u64int uncsize, used, aa;
36 u32int clump, clumps, cclumps, magic;
37 int err, flush, broken;
40 used = arena->memstats.used;
41 clumps = arena->memstats.clumps;
42 cclumps = arena->memstats.cclumps;
43 uncsize = arena->memstats.uncsize;
44 trace(TraceProc, "syncarena start");
48 aa = arena->memstats.used;
49 clump = arena->memstats.clumps;
50 magic = clumpmagic(arena, aa);
51 if(magic == ClumpFreeMagic)
53 if(magic != arena->clumpmagic){
54 fprint(2, "%s: illegal clump magic number=%#8.8ux at clump=%d\n", arena->name, magic, clump);
55 /* err |= SyncDataErr; */
56 if(fix && writeclumpmagic(arena, aa, ClumpFreeMagic) < 0){
57 fprint(2, "can't write corrected clump free magic: %r");
64 lump = loadclump(arena, aa, 0, &cl, score, 0);
66 fprint(2, "%s: clump=%d failed to read correctly: %r\n", arena->name, clump);
69 }else if(cl.info.type != VtCorruptType){
70 scoremem(score, lump->data, cl.info.uncsize);
71 if(scorecmp(cl.info.score, score) != 0){
72 /* ignore partially written block */
73 if(cl.encoding == ClumpENone)
75 fprint(2, "%s: clump=%d has mismatched score\n", arena->name, clump);
78 }else if(vttypevalid(cl.info.type) < 0){
79 fprint(2, "%s: clump=%d has invalid type %d", arena->name, clump, cl.info.type);
84 cl.info.type = VtCorruptType;
85 if(writeclumphead(arena, aa, &cl) < 0){
86 fprint(2, "%s: can't write corrected clump header: %r", arena->name);
92 arena->memstats.used += ClumpSize + cl.info.size;
94 arena->memstats.clumps++;
95 if(!broken && readclumpinfo(arena, clump, &ci)<0){
96 fprint(2, "%s: arena directory read failed\n", arena->name);
98 }else if(!broken && clumpinfocmp(&ci, &cl.info)!=0){
99 if(clumpinfocmp(&ci, &zci) == 0){
102 fprint(2, "%s: unwritten clump info for clump=%d\n", arena->name, clump);
105 fprint(2, "%s: bad clump info for clump=%d\n", arena->name, clump);
106 fprint(2, "\texpected score=%V type=%d size=%d uncsize=%d\n",
107 cl.info.score, cl.info.type, cl.info.size, cl.info.uncsize);
108 fprint(2, "\tfound score=%V type=%d size=%d uncsize=%d\n",
109 ci.score, ci.type, ci.size, ci.uncsize);
116 if(writeclumpinfo(arena, clump, &ci) < 0){
117 fprint(2, "%s: can't write correct clump directory: %r\n", arena->name);
121 trace(TraceProc, "syncarena unindexed clump %V %d", cl.info.score, arena->memstats.clumps);
123 arena->memstats.uncsize += cl.info.uncsize;
124 if(cl.info.size < cl.info.uncsize)
125 arena->memstats.cclumps++;
129 trace(TraceProc, "syncarena flush");
130 arena->wtime = now();
131 if(arena->ctime == 0 && arena->memstats.clumps)
132 arena->ctime = arena->wtime;
136 if(used != arena->memstats.used
137 || clumps != arena->memstats.clumps
138 || cclumps != arena->memstats.cclumps
139 || uncsize != arena->memstats.uncsize)
141 if(start && (err&SyncHeader)){
142 trace(TraceProc, "syncarena setdcachestate");
144 as.aa = start+arena->memstats.used;
145 as.stats = arena->memstats;
153 writeclumphead(Arena *arena, u64int aa, Clump *cl)
158 zb = alloczblock(ClumpSize, 0, arena->blocksize);
161 bad = packclump(cl, zb->data, arena->clumpmagic)<0
162 || writearena(arena, aa, zb->data, ClumpSize) != ClumpSize;
168 writeclumpmagic(Arena *arena, u64int aa, u32int magic)
172 packmagic(magic, buf);
173 return writearena(arena, aa, buf, U32Size) == U32Size;