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