format.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "logfsos.h"
  2. #include "logfs.h"
  3. #include "local.h"
  4. char *
  5. logfsformat(LogfsLowLevel *ll, long base, long limit, long bootsize, int trace)
  6. {
  7. long bootblocksdone, logblocksdone;
  8. long u;
  9. long baseblock, limitblock, bootblocks, sizeinblocks;
  10. int magicfound;
  11. void *llsave;
  12. if(trace > 1)
  13. print("logfsformat: base %ld limit %ld bootsize %lud\n", base, limit, bootsize);
  14. if((*ll->getopenstatus)(ll))
  15. return Eperm;
  16. if(!(*ll->calcformat)(ll, base, limit, bootsize, &baseblock, &limitblock, &bootblocks))
  17. return Ebadarg;
  18. if(trace > 0)
  19. print("logfsformat: baseblock %ld limitblock %ld bootblocks %ld\n", baseblock, limitblock, bootblocks);
  20. bootblocksdone = 0;
  21. logblocksdone = 0;
  22. /*
  23. * we need to create some fs blocks, and some boot blocks
  24. * the number of boot blocks is fixed; the number of fs blocks
  25. * occupies the remainder
  26. * the layout is randomised to:
  27. * 1) test the software
  28. * 2) spread wear around if a lot of format commands are issued by
  29. * the bootloader
  30. */
  31. sizeinblocks = limitblock - baseblock;
  32. for(u = 0; u < sizeinblocks; u++) {
  33. int r;
  34. uchar tag;
  35. long path;
  36. LogfsLowLevelReadResult e;
  37. char *errmsg;
  38. int markedbad;
  39. if(trace > 1)
  40. print("block %lud:", u);
  41. llsave = nil;
  42. errmsg = (*ll->getblockstatus)(ll, u + baseblock, &magicfound, &llsave, &e);
  43. if(errmsg)
  44. return errmsg;
  45. if(e == LogfsLowLevelReadResultBad) {
  46. if(trace > 1)
  47. print(" marked bad\n");
  48. continue;
  49. }
  50. errmsg = (*ll->eraseblock)(ll, u + baseblock, nil, &markedbad);
  51. if(errmsg)
  52. return errmsg;
  53. if(markedbad) {
  54. if(trace > 1)
  55. print(" marked bad\n");
  56. continue;
  57. }
  58. if(e != LogfsLowLevelReadResultHardError && magicfound) {
  59. if(trace > 1)
  60. print(" previously formatted");
  61. }
  62. r = nrand(sizeinblocks - u);
  63. if(bootblocksdone < bootblocks && r < (bootblocks - bootblocksdone)) {
  64. tag = LogfsTboot;
  65. path = mkdatapath(bootblocksdone, 0);
  66. }
  67. else {
  68. tag = LogfsTnone;
  69. path = ~0;
  70. }
  71. if(trace > 1)
  72. print(" tag %s path %ld", logfstagname(tag), path);
  73. errmsg = (*ll->formatblock)(ll, u + baseblock, tag, path, baseblock, sizeinblocks, 1, &bootblocks, llsave, &markedbad);
  74. logfsfreemem(llsave);
  75. if(errmsg)
  76. return errmsg;
  77. if(markedbad) {
  78. if(trace > 1)
  79. print(" marked bad\n");
  80. continue;
  81. }
  82. switch(tag) {
  83. case LogfsTboot:
  84. bootblocksdone++;
  85. break;
  86. case LogfsTnone:
  87. logblocksdone++;
  88. break;
  89. }
  90. if(trace > 1)
  91. print("\n");
  92. }
  93. if(bootblocksdone < bootblocks)
  94. return "not enough capacity left for boot";
  95. if(trace > 0)
  96. print("log blocks %lud\n", logblocksdone);
  97. return nil;
  98. }