📄 tfsclean.c
字号:
activesnum = snum + firstsnum; crctbl = defragCrcTable(tdp); /* Retrieve information about active sector: */ if (sectortoaddr(activesnum,&activessize,(uchar **)&activesbase) == -1) return(TFSERR_MEMFAIL); if (verbose) printf(" Active sector: %3d @ 0x%lx\n",activesnum,(ulong)activesbase); if (addrtosector((char *)tdp->end,&lastsnum,0,0) < 0) return(TFSERR_MEMFAIL); /* Establish a pointer to the defrag header table. * For the case when the active sector is the last sector, the defrag * header table will be in the spare, so we also establish a pointer * to that space... */ dhp = (struct defraghdr *)crctbl; dhp -= ftot; sdhp = (struct defraghdr *)(tdp->spare+activessize - (tdp->sectorcount * sizeof(struct sectorcrc))); sdhp -= ftot; activeaddr = activesbase; tmpactiveaddr = activesbase; activesend = activesbase + activessize - 1; /* FIRST LOOP: * See if we need to do anything... * In this state, we are simply checking to see if anything is going * to cause the currently active sector to be written to. * If yes, then we need to copy it to the spare and start the * modification process; else, we just return and do nothing * to this sector. * For each file in the defrag header table that is destined for * the address space occupied by the currently active sector, copy * that file (header and data) to the active sector... * Note that it may only be a partial copy, depending on the size * of the file and the amount of space left in the active sector. */ noreloctot = 0; new_fspan = SPANTYPE_UNDEF; lastfileisnotrelocated = 0; for(tot=0;tot<ftot;tot++,dhp++,sdhp++) { fullsize = TFSHDRSIZ + dhp->filsize; new_fbase = dhp->nda; new_fend = (new_fbase + fullsize); /* We must figure out how the new version of the file will * span across the active sector. * See defragGetSpantype() for details. */ new_fspan = defragGetSpantype(activesbase,activesend, new_fbase,new_fend); /* If the file we are looking at entirely spans a sector that is * prior to the currently active sector, then we just continue * through the list. * If the file entirely spans a sector that is after the * currently active sector, then we are done with this active sector. * If the file falls within the active sector in any way, and its * new location does not match its old location, then we * break out of this loop and begin the modification of this * active sector... */ if (new_fspan == SPANTYPE_BLEL) return(0); if (new_fspan != SPANTYPE_BPEP) { if (dhp->nda == (char *)dhp->ohdr) { noreloctot++; if (tot == ftot-1) { lastfileisnotrelocated = 1; if (verbose > 1) printf(" last file not relocated\n"); } } else break; } } /* If tot == ftot, then we got through the entire loop above without * finding a file that needs to be relocated into this active sector. * This means one of two things: either all the files fall into a * sector prior to this active sector, or the files in this active * sector do not need to be relocated. In either case, we simply * return without touching this sector. * Note that we also keep track of the possibility that the last file * may not be relocated. If this ends up to be the case, then we are * simply cleaning up one or more dead files after a full set of active * files, so we should clean up the sector. */ if ((tot == ftot) && (lastfileisnotrelocated == 0)) return(0); /* If tot != ftot, then we must subtract noreloctot from tot so that * we establish 'tot' as the index into the first file that must be * copied to the active sector... */ if (noreloctot) { tot -= noreloctot; dhp -= noreloctot; sdhp -= noreloctot; } /* Exit immediately before cleaning up the spare... */ defragExitTestPoint(10000+activesnum); /* Since we got here, we know that we have to do some work on the * currently active sector. We may not have to copy it to the spare, * but we will erase the spare anyway because the sector erase is * supposed to be smart enough to avoid the erase if it is already * erased. This should be handled by the flash driver because in * ALL cases the erase should be avoided if possible. */ if (defragEraseSpare(tdp) < 0) return(TFSERR_FLASHFAILURE); /* Exit immediately after cleaning up the spare... */ defragExitTestPoint(10001+activesnum); /* If the active sector is the last sector (which would contain the * defrag header table), then we reference the copy of the table that * is in the spare... * Also, if this is the last sector, then we HAVE to copy it to * spare, so we can skip the 2nd loop that attempts to determine * if we need to do it. */ if (activesnum == lastsnum) { dhp = sdhp; copytospare = 1; } else { /* SECOND LOOP: * See if we need to copy the active sector to the spare... * We do this by continuing the loop we started above. Notice that * we do an almost identical loop again below this. * On this pass through the loop we are only checking to see if it is * necessary to copy this active sector to the spare. */ tmptot = tot; tmpdhp = dhp; copytospare = 0; finfo.mode = FILLMODE_SPAREOVERLAP; for(;tmptot<ftot;tmptot++,tmpdhp++) { finfo.tdp = tdp; finfo.dhp = tmpdhp; finfo.asnum = activesnum; fullsize = TFSHDRSIZ + tmpdhp->filsize; new_fbase = tmpdhp->nda; new_fend = (new_fbase + fullsize); new_fspan = defragGetSpantype(activesbase,activesend, new_fbase,new_fend); if (new_fspan == SPANTYPE_BPEP) continue; else if (new_fspan == SPANTYPE_BLEL) break; /* Now retrieve span information about header and data * portions of the file (new and orig)... */ new_hbase = new_fbase; new_hend = new_hbase + TFSHDRSIZ; new_dbase = new_hbase + TFSHDRSIZ; new_dend = new_fend; orig_fend = ((char *)tmpdhp->ohdr + fullsize); new_hspan = defragGetSpantype(activesbase,activesend, new_hbase,new_hend); new_dspan = defragGetSpantype(activesbase,activesend, new_dbase,new_dend); /* If defragFillFlash() returns positive (with mode == * FILLMODE_SPAREOVERLAP set above), then we know that the * spare sector must be loaded with a copy of this active * sector, so we can break out of this loop at that point... */ finfo.fhdr = 1; fillstat = defragFillFlash(&finfo,new_hspan,&tmpactiveaddr,0); if (fillstat < 0) return(fillstat); if (fillstat > 0) { copytospare = 1; break; } if (new_hspan == SPANTYPE_BCEL) break; finfo.fhdr = 0; fillstat = defragFillFlash(&finfo,new_dspan,&tmpactiveaddr,0); if (fillstat < 0) return(fillstat); if (fillstat > 0) { copytospare = 1; break; } if (new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) break; } } finfo.mode = FILLMODE_FWRITE; defragExitTestPoint(10002+activesnum); if (copytospare) { defragTick(verbose);#if DEFRAG_TEST_ENABLED printf(" copying sector %d to spare\n",activesnum);#endif if (defragFwrite(6,(uchar *)tdp->spare,activesbase,activessize) == -1) { printf("Failed to copy active %d to spare\n",activesnum); return(TFSERR_FLASHFAILURE); } }#if DEFRAG_TEST_ENABLED else { printf(" copy saved\n"); }#endif defragTick(verbose); /* We can now begin actual modification of the active sector, * so start off by eraseing it... */ defragExitTestPoint(10003+activesnum); if (defragSerase(4,activesnum) < 0) return(TFSERR_FLASHFAILURE); defragExitTestPoint(10004+activesnum); /* THIRD LOOP: * Now we pass through the loop to do the real flash modifications... */ for(;tot<ftot;tot++,dhp++) { finfo.tdp = tdp; finfo.dhp = dhp; finfo.asnum = activesnum; fullsize = TFSHDRSIZ + dhp->filsize; new_fbase = dhp->nda; new_fend = (new_fbase + fullsize); new_fspan = defragGetSpantype(activesbase,activesend, new_fbase,new_fend); if (new_fspan == SPANTYPE_BPEP) continue; else if (new_fspan == SPANTYPE_BLEL) break; if (verbose) printf(" File: %s\n",dhp->fname); /* Now retrieve span information about header and data * portions of the file (new and orig)... */ new_hbase = new_fbase; new_hend = new_hbase + TFSHDRSIZ; new_dbase = new_hbase + TFSHDRSIZ; new_dend = new_fend; orig_fend = ((char *)dhp->ohdr + fullsize); new_hspan = defragGetSpantype(activesbase,activesend, new_hbase,new_hend); new_dspan = defragGetSpantype(activesbase,activesend, new_dbase,new_dend); /* At this point we have all the information we need to copy * the appropriate amount of the file from orignal space * to new space. * We have to break the write up into two parts, the header * (new_hspan) and the data (new_dspan) so we have to look * at the spantype for each to determine what part of the * header and/or data we are going to copy. * * Also, we must consider the possibility that the source * data may be in the spare sector. This would be the case * if the active sector is the same sector that the original * data was in. If the source data is in the spare sector, * then an added complication is the fact that it may not * all be there, we may have to copy some from the spare, * then some from the original space. */ finfo.fhdr = 1; fillstat = defragFillFlash(&finfo,new_hspan,&activeaddr,verbose); if (fillstat < 0) return(fillstat); if (new_hspan == SPANTYPE_BCEL) break; finfo.fhdr = 0; fillstat = defragFillFlash(&finfo,new_dspan,&activeaddr,verbose); if (fillstat < 0) return(fillstat); if (new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) break; defragTick(verbose); } return(0);}static intdefragNewSectorCrc(TDEV *tdp, struct defraghdr *dht, int snum, ulong *newcrc){ int firstsnum; /* number of first TFS sector */ int activesnum; /* number of sector currently being written to */ int activessize; /* size of active sector */ char *activeaddr; /* offset being written to in the active sector */ char *activesbase; /* base address of active sector */ char *activesend; /* end address of active sector */ struct defraghdr *dhp; /* pointer into defrag header table */ int fullsize; /* size of file and header */ char *new_dend; /* new end of data */ char *new_dbase; /* new base of data */ char *new_hend; /* new end of header */ char *new_hbase; /* new base of header */ char *new_fend; /* new end of file */ char *new_fbase; /* new base of file */ char *orig_fend; /* original end of file */ int new_fspan; /* span type for new file */ int new_hspan; /* span type for new header */ int new_dspan; /* span type for new data */ int fillstat; /* result of defragFillFlash() function call */ int ftot; char *tmpactiveaddr; struct fillinfo finfo; struct sectorcrc *crctbl; int lastsnum, tot, sz, temp; /* Retrieve number of first TFS sector: */ if (addrtosector((char *)tdp->start,&firstsnum,0,0) < 0) return(TFSERR_MEMFAIL); activesnum = snum + firstsnum; crctbl = defragCrcTable(tdp); /* Retrieve information about active sector: */ if (sectortoaddr(activesnum,&activessize,(uchar **)&activesbase) == -1) return(TFSERR_MEMFAIL); if (addrtosector((char *)tdp->end,&lastsnum,0,0) < 0) return(TFSERR_MEMFAIL); dhp = (struct defraghdr *)crctbl - 1; ftot = dhp->idx + 1; dhp = dht; activeaddr = activesbase; tmpactiveaddr = activesbase; activesend = activesbase + activessize - 1; finfo.tdp = tdp; finfo.crcsz = 0; finfo.crc = 0xffffffff; finfo.asnum = activesnum; finfo.mode = FILLMODE_CRCONLY; for(tot=0;tot<ftot;tot++,dhp++) { finfo.dhp = dhp; fullsize = TFSHDRSIZ + dhp->filsize; new_fbase = dhp->nda; new_fend = (new_fbase + fullsize); new_fspan = defragGetSpantype(activesbase,activesend, new_fbase,new_fend);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -