Blob


1 #include "stdinc.h"
2 #include "dat.h"
3 #include "fns.h"
5 static int verbose;
7 static void
8 checkarena(Arena *arena, int scan, int fix)
9 {
10 Arena old;
11 int err, e;
13 if(verbose && arena->clumps)
14 printarena(2, arena);
16 old = *arena;
18 if(scan){
19 arena->used = 0;
20 arena->clumps = 0;
21 arena->cclumps = 0;
22 arena->uncsize = 0;
23 }
25 err = 0;
26 for(;;){
27 e = syncarena(arena, 1000, 0, fix);
28 err |= e;
29 if(!(e & SyncHeader))
30 break;
31 if(verbose && arena->clumps)
32 fprint(2, ".");
33 }
34 if(verbose && arena->clumps)
35 fprint(2, "\n");
37 err &= ~SyncHeader;
38 if(arena->used != old.used
39 || arena->clumps != old.clumps
40 || arena->cclumps != old.cclumps
41 || arena->uncsize != old.uncsize){
42 fprint(2, "incorrect arena header fields\n");
43 printarena(2, arena);
44 err |= SyncHeader;
45 }
47 if(!err || !fix)
48 return;
50 fprint(2, "writing fixed arena header fields\n");
51 if(wbarena(arena) < 0)
52 fprint(2, "arena header write failed: %r\n");
53 }
55 void
56 usage(void)
57 {
58 fprint(2, "usage: checkarenas [-afv] file\n");
59 threadexitsall(0);
60 }
62 void
63 threadmain(int argc, char *argv[])
64 {
65 ArenaPart *ap;
66 Part *part;
67 char *file;
68 int i, fix, scan;
70 fmtinstall('V', vtscorefmt);
72 statsinit();
74 fix = 0;
75 scan = 0;
76 ARGBEGIN{
77 case 'f':
78 fix++;
79 break;
80 case 'a':
81 scan = 1;
82 break;
83 case 'v':
84 verbose++;
85 break;
86 default:
87 usage();
88 break;
89 }ARGEND
91 if(!fix)
92 readonly = 1;
94 if(argc != 1)
95 usage();
97 file = argv[0];
99 part = initpart(file, 0);
100 if(part == nil)
101 sysfatal("can't open partition %s: %r", file);
103 ap = initarenapart(part);
104 if(ap == nil)
105 sysfatal("can't initialize arena partition in %s: %r", file);
107 if(verbose > 1){
108 printarenapart(2, ap);
109 fprint(2, "\n");
112 initdcache(8 * MaxDiskBlock);
114 for(i = 0; i < ap->narenas; i++)
115 checkarena(ap->arenas[i], scan, fix);
117 if(verbose > 1)
118 printstats();
119 threadexitsall(0);