Blame


1 a0d146ed 2005-07-12 devnull #include "stdinc.h"
2 a0d146ed 2005-07-12 devnull #include "dat.h"
3 a0d146ed 2005-07-12 devnull #include "fns.h"
4 a0d146ed 2005-07-12 devnull
5 a0d146ed 2005-07-12 devnull static int writeclumphead(Arena *arena, u64int aa, Clump *cl);
6 a0d146ed 2005-07-12 devnull static int writeclumpmagic(Arena *arena, u64int aa, u32int magic);
7 a0d146ed 2005-07-12 devnull
8 a0d146ed 2005-07-12 devnull int
9 a0d146ed 2005-07-12 devnull clumpinfocmp(ClumpInfo *c, ClumpInfo *d)
10 a0d146ed 2005-07-12 devnull {
11 a0d146ed 2005-07-12 devnull return c->type != d->type
12 a0d146ed 2005-07-12 devnull || c->size != d->size
13 a0d146ed 2005-07-12 devnull || c->uncsize != d->uncsize
14 a0d146ed 2005-07-12 devnull || scorecmp(c->score, d->score)!=0;
15 a0d146ed 2005-07-12 devnull }
16 a0d146ed 2005-07-12 devnull
17 a0d146ed 2005-07-12 devnull /*
18 a0d146ed 2005-07-12 devnull * synchronize the clump info directory with
19 a0d146ed 2005-07-12 devnull * with the clumps actually stored in the arena.
20 a0d146ed 2005-07-12 devnull * the directory should be at least as up to date
21 a0d146ed 2005-07-12 devnull * as the arena's trailer.
22 a0d146ed 2005-07-12 devnull *
23 a0d146ed 2005-07-12 devnull * checks/updates at most n clumps.
24 a0d146ed 2005-07-12 devnull *
25 a0d146ed 2005-07-12 devnull * returns 0 if ok, flags if error occurred
26 a0d146ed 2005-07-12 devnull */
27 a0d146ed 2005-07-12 devnull int
28 45ac814c 2007-10-29 rsc syncarena(Arena *arena, u32int n, int zok, int fix)
29 a0d146ed 2005-07-12 devnull {
30 a0d146ed 2005-07-12 devnull ZBlock *lump;
31 a0d146ed 2005-07-12 devnull Clump cl;
32 a0d146ed 2005-07-12 devnull ClumpInfo ci;
33 28b49df3 2006-07-18 devnull static ClumpInfo zci = { .type = -1 };
34 a0d146ed 2005-07-12 devnull u8int score[VtScoreSize];
35 a0d146ed 2005-07-12 devnull u64int uncsize, used, aa;
36 a0d146ed 2005-07-12 devnull u32int clump, clumps, cclumps, magic;
37 a0d146ed 2005-07-12 devnull int err, flush, broken;
38 a0d146ed 2005-07-12 devnull
39 a0d146ed 2005-07-12 devnull used = arena->memstats.used;
40 a0d146ed 2005-07-12 devnull clumps = arena->memstats.clumps;
41 a0d146ed 2005-07-12 devnull cclumps = arena->memstats.cclumps;
42 a0d146ed 2005-07-12 devnull uncsize = arena->memstats.uncsize;
43 a0d146ed 2005-07-12 devnull trace(TraceProc, "syncarena start");
44 a0d146ed 2005-07-12 devnull flush = 0;
45 a0d146ed 2005-07-12 devnull err = 0;
46 a0d146ed 2005-07-12 devnull for(; n; n--){
47 a0d146ed 2005-07-12 devnull aa = arena->memstats.used;
48 a0d146ed 2005-07-12 devnull clump = arena->memstats.clumps;
49 a0d146ed 2005-07-12 devnull magic = clumpmagic(arena, aa);
50 a0d146ed 2005-07-12 devnull if(magic == ClumpFreeMagic)
51 a0d146ed 2005-07-12 devnull break;
52 a0d146ed 2005-07-12 devnull if(magic != arena->clumpmagic){
53 a0d146ed 2005-07-12 devnull fprint(2, "%s: illegal clump magic number=%#8.8ux at clump=%d\n", arena->name, magic, clump);
54 a0d146ed 2005-07-12 devnull /* err |= SyncDataErr; */
55 a0d146ed 2005-07-12 devnull if(fix && writeclumpmagic(arena, aa, ClumpFreeMagic) < 0){
56 45ac814c 2007-10-29 rsc fprint(2, "%s: can't write corrected clump free magic: %r", arena->name);
57 a0d146ed 2005-07-12 devnull err |= SyncFixErr;
58 a0d146ed 2005-07-12 devnull }
59 a0d146ed 2005-07-12 devnull break;
60 a0d146ed 2005-07-12 devnull }
61 a0d146ed 2005-07-12 devnull
62 a0d146ed 2005-07-12 devnull broken = 0;
63 a0d146ed 2005-07-12 devnull lump = loadclump(arena, aa, 0, &cl, score, 0);
64 a0d146ed 2005-07-12 devnull if(lump == nil){
65 a0d146ed 2005-07-12 devnull fprint(2, "%s: clump=%d failed to read correctly: %r\n", arena->name, clump);
66 a0d146ed 2005-07-12 devnull break;
67 a0d146ed 2005-07-12 devnull }else if(cl.info.type != VtCorruptType){
68 a0d146ed 2005-07-12 devnull scoremem(score, lump->data, cl.info.uncsize);
69 a0d146ed 2005-07-12 devnull if(scorecmp(cl.info.score, score) != 0){
70 a0d146ed 2005-07-12 devnull /* ignore partially written block */
71 a0d146ed 2005-07-12 devnull if(cl.encoding == ClumpENone)
72 a0d146ed 2005-07-12 devnull break;
73 a0d146ed 2005-07-12 devnull fprint(2, "%s: clump=%d has mismatched score\n", arena->name, clump);
74 a0d146ed 2005-07-12 devnull err |= SyncDataErr;
75 a0d146ed 2005-07-12 devnull broken = 1;
76 a0d146ed 2005-07-12 devnull }else if(vttypevalid(cl.info.type) < 0){
77 a0d146ed 2005-07-12 devnull fprint(2, "%s: clump=%d has invalid type %d", arena->name, clump, cl.info.type);
78 a0d146ed 2005-07-12 devnull err |= SyncDataErr;
79 a0d146ed 2005-07-12 devnull broken = 1;
80 a0d146ed 2005-07-12 devnull }
81 a0d146ed 2005-07-12 devnull if(broken && fix){
82 a0d146ed 2005-07-12 devnull cl.info.type = VtCorruptType;
83 a0d146ed 2005-07-12 devnull if(writeclumphead(arena, aa, &cl) < 0){
84 a0d146ed 2005-07-12 devnull fprint(2, "%s: can't write corrected clump header: %r", arena->name);
85 a0d146ed 2005-07-12 devnull err |= SyncFixErr;
86 a0d146ed 2005-07-12 devnull }
87 a0d146ed 2005-07-12 devnull }
88 a0d146ed 2005-07-12 devnull }
89 a0d146ed 2005-07-12 devnull freezblock(lump);
90 a0d146ed 2005-07-12 devnull arena->memstats.used += ClumpSize + cl.info.size;
91 a0d146ed 2005-07-12 devnull
92 a0d146ed 2005-07-12 devnull arena->memstats.clumps++;
93 a0d146ed 2005-07-12 devnull if(!broken && readclumpinfo(arena, clump, &ci)<0){
94 a0d146ed 2005-07-12 devnull fprint(2, "%s: arena directory read failed\n", arena->name);
95 a0d146ed 2005-07-12 devnull broken = 1;
96 a0d146ed 2005-07-12 devnull }else if(!broken && clumpinfocmp(&ci, &cl.info)!=0){
97 a0d146ed 2005-07-12 devnull if(clumpinfocmp(&ci, &zci) == 0){
98 a0d146ed 2005-07-12 devnull err |= SyncCIZero;
99 a0d146ed 2005-07-12 devnull if(!zok)
100 a0d146ed 2005-07-12 devnull fprint(2, "%s: unwritten clump info for clump=%d\n", arena->name, clump);
101 a0d146ed 2005-07-12 devnull }else{
102 a0d146ed 2005-07-12 devnull err |= SyncCIErr;
103 a0d146ed 2005-07-12 devnull fprint(2, "%s: bad clump info for clump=%d\n", arena->name, clump);
104 a0d146ed 2005-07-12 devnull fprint(2, "\texpected score=%V type=%d size=%d uncsize=%d\n",
105 a0d146ed 2005-07-12 devnull cl.info.score, cl.info.type, cl.info.size, cl.info.uncsize);
106 a0d146ed 2005-07-12 devnull fprint(2, "\tfound score=%V type=%d size=%d uncsize=%d\n",
107 a0d146ed 2005-07-12 devnull ci.score, ci.type, ci.size, ci.uncsize);
108 a0d146ed 2005-07-12 devnull }
109 a0d146ed 2005-07-12 devnull broken = 1;
110 a0d146ed 2005-07-12 devnull }
111 a0d146ed 2005-07-12 devnull if(broken && fix){
112 a0d146ed 2005-07-12 devnull flush = 1;
113 a0d146ed 2005-07-12 devnull ci = cl.info;
114 a0d146ed 2005-07-12 devnull if(writeclumpinfo(arena, clump, &ci) < 0){
115 a0d146ed 2005-07-12 devnull fprint(2, "%s: can't write correct clump directory: %r\n", arena->name);
116 a0d146ed 2005-07-12 devnull err |= SyncFixErr;
117 a0d146ed 2005-07-12 devnull }
118 a0d146ed 2005-07-12 devnull }
119 a0d146ed 2005-07-12 devnull trace(TraceProc, "syncarena unindexed clump %V %d", cl.info.score, arena->memstats.clumps);
120 a0d146ed 2005-07-12 devnull
121 a0d146ed 2005-07-12 devnull arena->memstats.uncsize += cl.info.uncsize;
122 a0d146ed 2005-07-12 devnull if(cl.info.size < cl.info.uncsize)
123 a0d146ed 2005-07-12 devnull arena->memstats.cclumps++;
124 a0d146ed 2005-07-12 devnull }
125 a0d146ed 2005-07-12 devnull
126 a0d146ed 2005-07-12 devnull if(flush){
127 a0d146ed 2005-07-12 devnull trace(TraceProc, "syncarena flush");
128 a0d146ed 2005-07-12 devnull arena->wtime = now();
129 a0d146ed 2005-07-12 devnull if(arena->ctime == 0 && arena->memstats.clumps)
130 a0d146ed 2005-07-12 devnull arena->ctime = arena->wtime;
131 a0d146ed 2005-07-12 devnull flushdcache();
132 a0d146ed 2005-07-12 devnull }
133 a0d146ed 2005-07-12 devnull
134 a0d146ed 2005-07-12 devnull if(used != arena->memstats.used
135 a0d146ed 2005-07-12 devnull || clumps != arena->memstats.clumps
136 a0d146ed 2005-07-12 devnull || cclumps != arena->memstats.cclumps
137 e6594f1a 2007-04-22 devnull || uncsize != arena->memstats.uncsize){
138 a0d146ed 2005-07-12 devnull err |= SyncHeader;
139 45ac814c 2007-10-29 rsc fprint(2, "arena %s: fix=%d flush=%d %lld->%lld %ud->%ud %ud->%ud %lld->%lld\n",
140 e6594f1a 2007-04-22 devnull arena->name,
141 e6594f1a 2007-04-22 devnull fix,
142 e6594f1a 2007-04-22 devnull flush,
143 e6594f1a 2007-04-22 devnull used, arena->memstats.used,
144 e6594f1a 2007-04-22 devnull clumps, arena->memstats.clumps,
145 e6594f1a 2007-04-22 devnull cclumps, arena->memstats.cclumps,
146 e6594f1a 2007-04-22 devnull uncsize, arena->memstats.uncsize);
147 e6594f1a 2007-04-22 devnull }
148 e6594f1a 2007-04-22 devnull
149 a0d146ed 2005-07-12 devnull return err;
150 a0d146ed 2005-07-12 devnull }
151 a0d146ed 2005-07-12 devnull
152 a0d146ed 2005-07-12 devnull static int
153 a0d146ed 2005-07-12 devnull writeclumphead(Arena *arena, u64int aa, Clump *cl)
154 a0d146ed 2005-07-12 devnull {
155 a0d146ed 2005-07-12 devnull ZBlock *zb;
156 a0d146ed 2005-07-12 devnull int bad;
157 a0d146ed 2005-07-12 devnull
158 a0d146ed 2005-07-12 devnull zb = alloczblock(ClumpSize, 0, arena->blocksize);
159 a0d146ed 2005-07-12 devnull if(zb == nil)
160 a0d146ed 2005-07-12 devnull return -1;
161 a0d146ed 2005-07-12 devnull bad = packclump(cl, zb->data, arena->clumpmagic)<0
162 a0d146ed 2005-07-12 devnull || writearena(arena, aa, zb->data, ClumpSize) != ClumpSize;
163 a0d146ed 2005-07-12 devnull freezblock(zb);
164 a0d146ed 2005-07-12 devnull return bad ? -1 : 0;
165 a0d146ed 2005-07-12 devnull }
166 a0d146ed 2005-07-12 devnull
167 a0d146ed 2005-07-12 devnull static int
168 a0d146ed 2005-07-12 devnull writeclumpmagic(Arena *arena, u64int aa, u32int magic)
169 a0d146ed 2005-07-12 devnull {
170 a0d146ed 2005-07-12 devnull u8int buf[U32Size];
171 a0d146ed 2005-07-12 devnull
172 a0d146ed 2005-07-12 devnull packmagic(magic, buf);
173 a0d146ed 2005-07-12 devnull return writearena(arena, aa, buf, U32Size) == U32Size;
174 a0d146ed 2005-07-12 devnull }