fmtarenas.c (2701B)
1 #include "stdinc.h" 2 #include "dat.h" 3 #include "fns.h" 4 5 void 6 usage(void) 7 { 8 fprint(2, "usage: fmtarenas [-4Z] [-a arenasize] [-b blocksize] name file\n"); 9 threadexitsall(0); 10 } 11 12 void 13 threadmain(int argc, char *argv[]) 14 { 15 int vers; 16 ArenaPart *ap; 17 Part *part; 18 Arena *arena; 19 u64int addr, limit, asize, apsize; 20 char *file, *name, aname[ANameSize]; 21 int i, n, blocksize, tabsize, zero; 22 23 ventifmtinstall(); 24 statsinit(); 25 26 blocksize = 8 * 1024; 27 asize = 512 * 1024 *1024; 28 tabsize = 512 * 1024; /* BUG: should be determine from number of arenas */ 29 zero = -1; 30 vers = ArenaVersion5; 31 ARGBEGIN{ 32 case 'D': 33 settrace(EARGF(usage())); 34 break; 35 case 'a': 36 asize = unittoull(EARGF(usage())); 37 if(asize == TWID64) 38 usage(); 39 break; 40 case 'b': 41 blocksize = unittoull(EARGF(usage())); 42 if(blocksize == ~0) 43 usage(); 44 if(blocksize > MaxDiskBlock){ 45 fprint(2, "block size too large, max %d\n", MaxDiskBlock); 46 threadexitsall("usage"); 47 } 48 break; 49 case '4': 50 vers = ArenaVersion4; 51 break; 52 case 'Z': 53 zero = 0; 54 break; 55 default: 56 usage(); 57 break; 58 }ARGEND 59 60 if(zero == -1){ 61 if(vers == ArenaVersion4) 62 zero = 1; 63 else 64 zero = 0; 65 } 66 67 if(argc != 2) 68 usage(); 69 70 name = argv[0]; 71 file = argv[1]; 72 73 if(nameok(name) < 0) 74 sysfatal("illegal name template %s", name); 75 76 part = initpart(file, ORDWR|ODIRECT); 77 if(part == nil) 78 sysfatal("can't open partition %s: %r", file); 79 80 if(zero) 81 zeropart(part, blocksize); 82 83 maxblocksize = blocksize; 84 initdcache(20*blocksize); 85 86 ap = newarenapart(part, blocksize, tabsize); 87 if(ap == nil) 88 sysfatal("can't initialize arena: %r"); 89 90 apsize = ap->size - ap->arenabase; 91 n = apsize / asize; 92 if(apsize - (n * asize) >= MinArenaSize) 93 n++; 94 95 fprint(2, "fmtarenas %s: %,d arenas, %,lld bytes storage, %,d bytes for index map\n", 96 file, n, apsize, ap->tabsize); 97 98 ap->narenas = n; 99 ap->map = MKNZ(AMap, n); 100 ap->arenas = MKNZ(Arena*, n); 101 102 addr = ap->arenabase; 103 for(i = 0; i < n; i++){ 104 limit = addr + asize; 105 if(limit >= ap->size || ap->size - limit < MinArenaSize){ 106 limit = ap->size; 107 if(limit - addr < MinArenaSize) 108 sysfatal("bad arena set math: runt arena at %lld,%lld %lld", addr, limit, ap->size); 109 } 110 111 snprint(aname, ANameSize, "%s%d", name, i); 112 113 if(0) fprint(2, "adding arena %s at [%lld,%lld)\n", aname, addr, limit); 114 115 arena = newarena(part, vers, aname, addr, limit - addr, blocksize); 116 if(!arena) 117 fprint(2, "can't make new arena %s: %r", aname); 118 freearena(arena); 119 120 ap->map[i].start = addr; 121 ap->map[i].stop = limit; 122 namecp(ap->map[i].name, aname); 123 124 addr = limit; 125 } 126 127 if(wbarenapart(ap) < 0) 128 fprint(2, "can't write back arena partition header for %s: %r\n", file); 129 130 flushdcache(); 131 threadexitsall(0); 132 }