123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- #include "logfsos.h"
- #include "logfs.h"
- #include "local.h"
- char *
- logfsformat(LogfsLowLevel *ll, long base, long limit, long bootsize, int trace)
- {
- long bootblocksdone, logblocksdone;
- long u;
- long baseblock, limitblock, bootblocks, sizeinblocks;
- int magicfound;
- void *llsave;
- if(trace > 1)
- print("logfsformat: base %ld limit %ld bootsize %lud\n", base, limit, bootsize);
- if((*ll->getopenstatus)(ll))
- return Eperm;
- if(!(*ll->calcformat)(ll, base, limit, bootsize, &baseblock, &limitblock, &bootblocks))
- return Ebadarg;
- if(trace > 0)
- print("logfsformat: baseblock %ld limitblock %ld bootblocks %ld\n", baseblock, limitblock, bootblocks);
- bootblocksdone = 0;
- logblocksdone = 0;
- /*
- * we need to create some fs blocks, and some boot blocks
- * the number of boot blocks is fixed; the number of fs blocks
- * occupies the remainder
- * the layout is randomised to:
- * 1) test the software
- * 2) spread wear around if a lot of format commands are issued by
- * the bootloader
- */
- sizeinblocks = limitblock - baseblock;
- for(u = 0; u < sizeinblocks; u++) {
- int r;
- uchar tag;
- long path;
- LogfsLowLevelReadResult e;
- char *errmsg;
- int markedbad;
- if(trace > 1)
- print("block %lud:", u);
- llsave = nil;
- errmsg = (*ll->getblockstatus)(ll, u + baseblock, &magicfound, &llsave, &e);
- if(errmsg)
- return errmsg;
- if(e == LogfsLowLevelReadResultBad) {
- if(trace > 1)
- print(" marked bad\n");
- continue;
- }
- errmsg = (*ll->eraseblock)(ll, u + baseblock, nil, &markedbad);
- if(errmsg)
- return errmsg;
- if(markedbad) {
- if(trace > 1)
- print(" marked bad\n");
- continue;
- }
- if(e != LogfsLowLevelReadResultHardError && magicfound) {
- if(trace > 1)
- print(" previously formatted");
- }
- r = nrand(sizeinblocks - u);
- if(bootblocksdone < bootblocks && r < (bootblocks - bootblocksdone)) {
- tag = LogfsTboot;
- path = mkdatapath(bootblocksdone, 0);
- }
- else {
- tag = LogfsTnone;
- path = ~0;
- }
- if(trace > 1)
- print(" tag %s path %ld", logfstagname(tag), path);
- errmsg = (*ll->formatblock)(ll, u + baseblock, tag, path, baseblock, sizeinblocks, 1, &bootblocks, llsave, &markedbad);
- logfsfreemem(llsave);
- if(errmsg)
- return errmsg;
- if(markedbad) {
- if(trace > 1)
- print(" marked bad\n");
- continue;
- }
- switch(tag) {
- case LogfsTboot:
- bootblocksdone++;
- break;
- case LogfsTnone:
- logblocksdone++;
- break;
- }
- if(trace > 1)
- print("\n");
- }
- if(bootblocksdone < bootblocks)
- return "not enough capacity left for boot";
- if(trace > 0)
- print("log blocks %lud\n", logblocksdone);
- return nil;
- }
|