ref: 163dccbac04a3c9ab132005ebb4a96a0e0baec0b
dir: /sys/src/cmd/venti/srv/checkarenas.c/
#include "stdinc.h" #include "dat.h" #include "fns.h" static int verbose; static void checkarena(Arena *arena, int scan, int fix) { ATailStats old; int err, e; if(verbose && arena->memstats.clumps) printarena(2, arena); old = arena->memstats; if(scan){ arena->memstats.used = 0; arena->memstats.clumps = 0; arena->memstats.cclumps = 0; arena->memstats.uncsize = 0; } err = 0; for(;;){ e = syncarena(arena, 1000, 0, fix); err |= e; if(!(e & SyncHeader)) break; if(verbose && arena->memstats.clumps) fprint(2, "."); } if(verbose && arena->memstats.clumps) fprint(2, "\n"); err &= ~SyncHeader; if(arena->memstats.used != old.used || arena->memstats.clumps != old.clumps || arena->memstats.cclumps != old.cclumps || arena->memstats.uncsize != old.uncsize){ fprint(2, "%s: incorrect arena header fields\n", arena->name); printarena(2, arena); err |= SyncHeader; } if(!err || !fix) return; fprint(2, "%s: writing fixed arena header fields\n", arena->name); arena->diskstats = arena->memstats; if(wbarena(arena) < 0) fprint(2, "arena header write failed: %r\n"); flushdcache(); } void usage(void) { fprint(2, "usage: checkarenas [-afv] file [arenaname...]\n"); threadexitsall(0); } int should(char *name, int argc, char **argv) { int i; if(argc == 0) return 1; for(i=0; i<argc; i++) if(strcmp(name, argv[i]) == 0) return 1; return 0; } void threadmain(int argc, char *argv[]) { ArenaPart *ap; Part *part; char *file; int i, fix, scan; ventifmtinstall(); statsinit(); fix = 0; scan = 0; ARGBEGIN{ case 'f': fix++; break; case 'a': scan = 1; break; case 'v': verbose++; break; default: usage(); break; }ARGEND if(!fix) readonly = 1; if(argc < 1) usage(); file = argv[0]; argc--; argv++; part = initpart(file, (fix ? ORDWR : OREAD)|ODIRECT); if(part == nil) sysfatal("can't open partition %s: %r", file); ap = initarenapart(part); if(ap == nil) sysfatal("can't initialize arena partition in %s: %r", file); if(verbose > 1){ printarenapart(2, ap); fprint(2, "\n"); } initdcache(8 * MaxDiskBlock); for(i = 0; i < ap->narenas; i++) if(should(ap->arenas[i]->name, argc, argv)) { debugarena = i; checkarena(ap->arenas[i], scan, fix); } if(verbose > 1) printstats(); threadexitsall(0); }