tfsclean1.c
来自「umon bootloader source code, support mip」· C语言 代码 · 共 2,107 行 · 第 1/5 页
C
2,107 行
case SCANNING_ACTIVE_SECTOR_5:
defrag_state = SCANNING_ACTIVE_SECTOR;
break;
}
}
else {
defrag_state = SECTOR_DEFRAG_INACTIVE;
}
if (verbose || restart || (!MFLAGS_NODEFRAGPRN())) {
printf("TFS device '%s' powersafe defragmentation\n",tdp->prefix);
if ((restart) && pollConsole("ok?")) {
printf("aborted\n");
return(TFS_OKAY);
}
}
if (addrtosector((char *)tdp->start,&firstsnum,0,0) < 0)
return(TFSERR_MEMFAIL);
lastsnum = firstsnum + tdp->sectorcount - 1;
if (addrtosector((char *)tdp->end,§orcheck,0,0) < 0)
return(TFSERR_MEMFAIL);
if (lastsnum != sectorcheck) {
/* If this error occurs, it is an indication that TFS was not
* properly configured in config.h, this error should not occur
* if TFS is properly configured.
*/
printf("%s: SECTORCOUNT != TFSSTART <-> TFSEND\n", tdp->prefix);
printf("First TFS sector = %d, last = %d\n",firstsnum,sectorcheck);
return(TFSERR_MEMFAIL);
}
if (defrag_state == SECTOR_DEFRAG_INACTIVE) {
activesnum = firstsnum;
}
/* Retrieve information about last sector:
*/
if (sectortoaddr(lastsnum,&lastssize,&lastsbase) == -1)
return(TFSERR_MEMFAIL);
/* Establish a pointer to a table of CRCs that will contain
* one 32-bit CRC for each sector (prior to starting the defrag).
*/
crctbl = defragCrcTable(tdp);
/* Retrieve the number of "dead" and "living" files:
* If there are no dead files, then there is no need to defrag.
* If there are no "living" files, then we can just init the flash.
*/
ftot = dtot = 0;
if (restart && defragValidDSI(tdp,0)) {
dht = (struct defraghdr *)crctbl - 1;
ftot = dht->idx + 1;
}
else {
tfp = (TFILE *)tdp->start;
while(validtfshdr(tfp)) {
if (TFS_FILEEXISTS(tfp))
ftot++;
else
dtot++;
tfp = nextfp(tfp,tdp);
}
if (dtot == 0) {
if (verbose)
printf("No dead files in %s.\n",tdp->prefix);
if (tfsflasherased(tdp,verbose))
return(0);
if (verbose)
printf("Cleaning up end of flash...\n");
}
}
if (ftot == 0) {
if (verbose)
printf("No active files detected, erasing all %s flash...\n",
tdp->prefix);
_tfsinit(tdp);
return(0);
}
/* Now that we know how many files are in TFS, we can establish
* a pointer to the defrag header table, and the size of the table...
*/
dht = (struct defraghdr *)crctbl - ftot;
dhstsize = (ulong)(tdp->end+1) - (ulong)dht;
dhstsize += 4; /* Account for the CRC of the state tables. */
if (defrag_state == SECTOR_DEFRAG_INACTIVE) {
ulong crc;
if (verbose) {
printf("TFS defrag: building DSI space...\n");
}
/* We start by making sure that the space needed by the
* defrag header and state table at the end of the last
* sector is clear...
*/
if (!flasherased((uchar *)dht, (uchar *)(tdp->end))) {
if (defragEraseSpare(tdp) < 0)
return(TFSERR_FLASHFAILURE);
if (defragFwrite(9,(uchar *)(tdp->spare),lastsbase,
lastssize-dhstsize) == -1) {
return(TFSERR_FLASHFAILURE);
}
if (defragSerase(5,lastsnum) < 0) {
return(TFSERR_FLASHFAILURE);
}
if (defragFwrite(10,lastsbase,(uchar *)(tdp->spare),
lastssize) == -1) {
return(TFSERR_FLASHFAILURE);
}
}
/* Erase the spare then copy the portion of the last TFS
* sector that does not overlap with the defrag header and
* state table area to the spare. We do this so that the spare
* sector contains a defrag header and state table area that
* is erased.
*/
if (defragEraseSpare(tdp) < 0)
return(TFSERR_FLASHFAILURE);
if (defragFwrite(11,(uchar *)tdp->spare,
lastsbase,lastssize-dhstsize) == -1) {
return(TFSERR_FLASHFAILURE);
}
/* At this point we have a valid copy of the last sector in
* the spare. If any portion of the last sector is not identical
* to what is in the spare, then we need to erase the last sector
* and re-copy what is in the spare to the last sector. This is
* necessary because an interrupt may have occurred while writing
* to the last sector, and it may have corrupted something.
*/
if ((memcmp(lastsbase,(char *)(tdp->spare),lastssize-dhstsize)) ||
(!flasherased((uchar *)dht,(uchar *)tdp->end))) {
if (defragSerase(6,lastsnum) < 0) {
return(TFSERR_FLASHFAILURE);
}
if (defragFwrite(12,lastsbase,(uchar *)(tdp->spare),
lastssize) == -1) {
return(TFSERR_FLASHFAILURE);
}
}
/* Build the header table:
*/
fcnt = 0;
tfp = (TFILE *)tdp->start;
newaddress = (char *)tdp->start;
if (verbose > 2) {
printf("\nDEFRAG HEADER DATA (dht=0x%lx, ftot=%d):\n",
(ulong)dht,ftot);
}
while(validtfshdr(tfp)) {
if (TFS_FILEEXISTS(tfp)) {
uchar *base, *eof, *neof, *nbase;
int size, slot;
struct tfsdat *slotptr;
strcpy(defrag.fname,TFS_NAME(tfp));
defrag.ohdr = tfp;
defrag.ohdrcrc = tfp->hdrcrc;
defrag.filsize = TFS_SIZE(tfp);
if (addrtosector((char *)tfp,0,0,&base) < 0)
return(TFSERR_MEMFAIL);
eof = (uchar *)(tfp+1)+TFS_SIZE(tfp)-1;
if (addrtosector((char *)eof,0,0,&base) < 0)
return(TFSERR_MEMFAIL);
defrag.oeso = eof - base + 1;
neof = newaddress+TFSHDRSIZ+TFS_SIZE(tfp)-1;
if (addrtosector((char *)neof,(int *)&defrag.nesn,0,&nbase) < 0)
return(TFSERR_MEMFAIL);
defrag.neso = neof - nbase + 1;
defrag.crc = 0;
defrag.idx = fcnt;
defrag.nda = newaddress;
/* If the file is currently opened, adjust the base address. */
slotptr = tfsSlots;
for (slot=0;slot<TFS_MAXOPEN;slot++,slotptr++) {
if (slotptr->offset != -1) {
if (slotptr->base == (uchar *)(TFS_BASE(tfp))) {
slotptr->base = (uchar *)(newaddress+TFSHDRSIZ);
}
}
}
size = TFS_SIZE(tfp) + TFSHDRSIZ;
if (size & 0xf) {
size += TFS_FSIZEMOD;
size &= ~(TFS_FSIZEMOD-1);
}
newaddress += size;
defrag.nextfile = (TFILE *)newaddress;
defrag.crc = crc32((uchar *)&defrag,DEFRAGHDRSIZ);
if (verbose > 2) {
printf(" File %s:\n",TFS_NAME(tfp));
printf(" nda= 0x%08lx, ohdr= 0x%08lx, nxt= 0x%08lx\n",
(ulong)(defrag.nda),(ulong)(defrag.ohdr),
(ulong)(defrag.nextfile));
printf(" oeso= 0x%08lx, nesn= 0x%08lx, neso= 0x%08lx\n",
(ulong)(defrag.oeso),(ulong)(defrag.nesn),
(ulong)(defrag.neso));
}
if (defragFwrite(13,(uchar *)(&dht[fcnt]),
(uchar *)(&defrag),DEFRAGHDRSIZ) == -1) {
return(TFSERR_FLASHFAILURE);
}
fcnt++;
defragTick(0);
}
tfp = nextfp(tfp,tdp);
}
if (defragBuildCrcTable(tdp,dht,verbose) < 0)
return(TFSERR_FLASHFAILURE);
/* Now, the last part of the state table build is to store a
* 32-bit crc of the data we just wrote...
*/
crc = crc32((uchar *)dht,(uchar *)tdp->end - (uchar *)dht);
if (defragFwrite(14,(uchar *)((ulong *)dht-1),(uchar *)&crc,4) == -1) {
return(TFSERR_FLASHFAILURE);
}
defrag_state = SCANNING_ACTIVE_SECTOR;
}
/* Exit here to have a complete defrag header installed. */
defragExitTestPoint(1000);
if (defrag_state == SCANNING_ACTIVE_SECTOR) {
if (verbose) {
printf("TFS: updating sectors %d-%d...\n",
activesnum,lastsnum);
}
/* Now we begin the actual defragmentation. We have built enough
* state information (defrag header and state table) into the last
* TFS sector, so now we can start the cleanup.
*/
for(sidx = activesnum - firstsnum; sidx < tdp->sectorcount; sidx++) {
if (defragFillActiveSector(tdp,ftot,sidx,verbose) < 0)
return(TFSERR_FLASHFAILURE);
}
defrag_state = SECTOR_DEFRAG_ALMOST_DONE;
}
/* Exit here to test "almost-done" state detection. */
defragExitTestPoint(1001);
if (defrag_state == SECTOR_DEFRAG_ALMOST_DONE) {
/* We've completed the relocation of all files into a defragmented
* area of TFS flash space. Now we have to erase all sectors after
* the sector used by the last file in TFS (including the spare)...
* If the last file in TFS uses the last sector, then the defrag
* header table will be erased and there is nothing left to do
* except erase the spare.
*/
if (verbose) {
printf("TFS: clearing available space...\n");
}
if (dht[ftot-1].crc != ERASED32) {
end = (dht[ftot-1].nda + dht[ftot-1].filsize + TFSHDRSIZ) - 1;
if (addrtosector(end,&snum,0,0) < 0)
return(TFSERR_FLASHFAILURE);
snum++;
while(snum <= lastsnum) {
if (defragSerase(7,snum) < 0)
return(TFSERR_FLASHFAILURE);
snum++;
defragTick(0);
}
}
if (defragEraseSpare(tdp) < 0)
return(TFSERR_FLASHFAILURE);
/* All defragmentation is done, so verify sanity of files... */
chkstat = tfscheck(tdp,verbose);
}
else {
chkstat = TFS_OKAY;
}
if ((verbose) || (!MFLAGS_NODEFRAGPRN()))
printf("Defragmentation complete\n");
return(chkstat);
}
/* tfsfixup():
* Called at system startup to finish up a TFS defragmentation if one
* was in progress.
*/
int
tfsfixup(int verbose, int dontquery)
{
TDEV *tdp;
/* Clear test data... */
DefragTestType = 0;
DefragTestPoint = 0;
DefragTestSector = 0;
#if !DEFRAG_TEST_ENABLED
tfsTrace = 99;
#endif
/* For each TFS device, run defrag with "fixup" flag set to let
* the defragger know that it should only defrag if a defrag was
* in progress.
*/
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
/* Call tfsclean() with fixup flag set... */
#if TFS_VERBOSE_STARTUP
if (StateOfMonitor == INITIALIZE)
printf("^oo^ TFS Scanning %s...\n",tdp->prefix);
#endif
_tfsclean(tdp,1,99);
}
#if !DEFRAG_TEST_ENABLED
tfsTrace = 0;
#endif
return(0);
}
#if DEFRAG_TEST_ENABLED
int
dumpDhdr(DEFRAGHDR *dhp)
{
printf("ohdr: 0x%08lx\n",(ulong)dhp->ohdr);
printf("nextfile: 0x%08lx\n",(ulong)dhp->nextfile);
printf("filsize: 0x%08lx\n",(ulong)dhp->filsize);
printf("crc: 0x%08lx\n",(ulong)dhp->crc);
printf("idx: 0x%08lx\n",(ulong)dhp->idx);
printf("nesn: 0x%08lx\n",(ulong)dhp->nesn);
printf("neso: 0x%08lx\n",(ulong)dhp->neso);
printf("nda: 0x%08lx\n",(ulong)dhp->nda);
printf("fname: %s\n",dhp->fname);
return(TFS_OKAY);
}
int
dumpDhdrTbl(DEFRAGHDR *dhp, int ftot)
{
TDEV *tdp;
uchar *sbase;
ulong *crc, calccrc;
int i, ssize, snum;
struct sectorcrc *crctbl;
for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
if (!dhp) {
crctbl = defragCrcTable(tdp);
printf("Device %s...\n",tdp->prefix);
dhp = (struct defraghdr *)crctbl - 1;
ftot = dhp->idx + 1;
printf("(%d files):\n",ftot);
dhp = (struct defraghdr *)crctbl - ftot;
crc = (ulong *)dhp-1;
if (*crc != crc32((uchar *)dhp,(uchar *)tdp->end - (uchar *)dhp)) {
printf("Table CRC failure\n");
return(TFS_OKAY);
}
}
else
crctbl = (struct sectorcrc *)(dhp + ftot);
printf("dhp=0x%lx, ftot=%d\n",(ulong)dhp,ftot);
while(dhp < (struct defraghdr *)crctbl) {
printf(" %s (dhp=0x%lx, idx=%ld):\n",
dhp->fname,(ulong)dhp,dhp->idx);
printf(" nda: 0x%08lx, ohdr: 0x%08lx\n",
(ulong)dhp->nda,(ulong)dhp->ohdr);
dhp++;
}
sbase = (uchar *)tdp->start;
printf("crctbl at 0x%lx\n",(ulong)crctbl);
for(i=0;i<tdp->sectorcount;i++) {
if (addrtosector(sbase,&snum,&ssize,0) < 0)
return(0);
if (i == tdp->sectorcount-1) {
ssize -= /* CRC table */
(tdp->sectorcount * sizeof(struct sectorcrc));
ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */
ssize -= 4; /* Crc of the tables */
}
calccrc = crc32(sbase,ssize);
if (calccrc == crctbl[i].precrc)
printf("crctbl[%d] (snum=%d) pre-pass\n",i,snum);
else if (calccrc == crctbl[i].postcrc)
printf("crctbl[%d] (snum=%d) post-pass\n",i,snum);
else {
printf("crctbl[%d] (snum=%d) test failed\n",i,snum);
printf("pre: 0x%lx, post: 0x%lx,calc: 0x%lx\n",
crctbl[i].precrc,crctbl[i].postcrc,calccrc);
}
sbase += ssize;
}
}
return(TFS_OKAY);
}
#endif /* DEFRAG_TEST_ENABLED */
#endif /* INCLUDE_TF
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?