Blob
1 #include "stdinc.h"2 #include "dat.h"3 #include "fns.h"5 static int verbose;7 static void8 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.used39 || arena->clumps != old.clumps40 || arena->cclumps != old.cclumps41 || 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 void56 usage(void)57 {58 fprint(2, "usage: checkarenas [-afv] file\n");59 threadexitsall(0);60 }62 void63 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 }ARGEND91 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");110 }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);120 }