fmtarenas.c 2.6 KB

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