?? tfs_with_appexit_support.c
字號:
TEST_EXIT_POINT(14,tfssector); } else { TEST_EXIT_POINT(15,tfssector); /* Copy TFS sector to SPARE, then update state. */ if (tfsflashwrite(TFSSPARE,sbase,ssize) < 0) { printf("Flash sector %d copy failed\n",tfssector); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(16,tfssector); if (setdefragstate(sidx,SECTOR_COPIED_TO_SPARE,verbose)!=TFS_OKAY) return(TFSERR_FLASHFAILURE); TEST_EXIT_POINT(17,tfssector);sector_copied_to_spare: dummy = 1; } TEST_EXIT_POINT(18,tfssector); /* Erase the sector within valid TFS space, then update state. */ if (tfsflasherase(tfssector) < 0) { printf("Flash sector erase (%d) failed\n",tfssector); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(19,tfssector); if (setdefragstate(sidx,SECTOR_UPDATE_STARTED,verbose) != TFS_OKAY) return(TFSERR_FLASHFAILURE);sector_update_started: /* Step through the defrag file header table and copy all files that */ /* have valid data in the sector that is now in SPARE space. Then */ /* update state. */ dp = defraghdrtbl; while (dp < (struct defraghdr *)DefragStateTbl) { if ((tfssector < dp->bsn) || (tfssector > dp->esn)) { dp++; continue; } if (verbose > 1) printf(" File %s:\n",dp->fhdr.name); if (dp->bsn == dp->esn) { /* Whole file is in SPARE */ if (verbose > 1) printf(" Complete_copy (nda=0x%x,nxt=0x%x,size=%d)\n", dp->nda,dp->fhdr.next,dp->fhdr.filsize+TFSHDRSIZ); TEST_EXIT_POINT(20,tfssector); /* Copy the header from defraghdrtbl[]... */ if (tfsflashwrite(dp->nda,&dp->fhdr,TFSHDRSIZ) == -1) { printf("Sector-update1.1 (dp=0x%x) failed\n",dp); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(21,tfssector); /* Copy the file data from SPARE... */ if (tfsflashwrite(dp->nda+TFSHDRSIZ,TFSSPARE+dp->bso+TFSHDRSIZ, dp->fhdr.filsize) == -1) { printf("Sector-update1.2 (dp=0x%x) failed\n",dp); return(TFSERR_FLASHFAILURE); } } else if (tfssector == dp->bsn) {/* Start of file is in SPARE */ fsize = (ssize - dp->bso) - TFSHDRSIZ; if (verbose > 1) printf(" Startof_copy (nda=0x%x,nxt=0x%x,size=%d)\n", dp->nda,dp->fhdr.next,fsize+TFSHDRSIZ); TEST_EXIT_POINT(22,tfssector); /* Copy the header from defraghdrtbl[]... */ if (tfsflashwrite(dp->nda,&dp->fhdr,TFSHDRSIZ) == -1) { printf("Sector-update2.1 (dp=0x%x) failed\n",dp); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(23,tfssector); if (tfsflashwrite(dp->nda+TFSHDRSIZ, TFSSPARE+dp->bso+TFSHDRSIZ,fsize) == -1) { printf("Sector-update2 (dp=0x%x) failed\n",dp); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(24,tfssector); } else if (tfssector == dp->esn) {/* End of file is in SPARE */ int offset; if (getndaoffset(dp,tfssector,&offset) == -1) return(TFSERR_FLASHFAILURE); if (verbose > 1) printf(" Endof_copy (nda offset=0x%x, size=%d)\n", offset,dp->eso); TEST_EXIT_POINT(25,tfssector); if (tfsflashwrite(dp->nda+offset,TFSSPARE,dp->eso) == -1) { printf("Sector-update3 (dp=0x%x) failed\n",dp); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(26,tfssector); } else { /* Middle of file is in SPARE */ int offset; if (getndaoffset(dp,tfssector,&offset) == -1) return(TFSERR_FLASHFAILURE); if (verbose > 1) printf(" Middleof_copy (nda offset=0x%x, size=%d)\n", offset,ssize); TEST_EXIT_POINT(27,tfssector); if (tfsflashwrite(dp->nda+offset,TFSSPARE,ssize) == -1) { printf("Sector-update4 (dp=0x%x) failed\n",dp); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(28,tfssector); } dp++; } TEST_EXIT_POINT(29,tfssector); if (setdefragstate(sidx,SECTOR_UPDATE_COMPLETE,verbose)!=TFS_OKAY) return(TFSERR_FLASHFAILURE); TEST_EXIT_POINT(30,tfssector);sector_update_complete: /* Erase the SPARE sector, then update state. */ if (tfssector != lasttfssector) { if (tfsflasherase(sparesnum) < 0) { printf("Flash SPARE sector erase failed\n"); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(31,tfssector); } TEST_EXIT_POINT(32,tfssector);sector_defrag_skip: if (setdefragstate(sidx,SECTOR_DEFRAG_COMPLETE,verbose)!=TFS_OKAY) return(TFSERR_FLASHFAILURE);sector_defrag_complete: sbase += ssize; if (addrtosector(sbase,0,&ssize,0) < 0) return(TFSERR_MEMFAIL); } /* If the last file copy did not enter the last tfssector, then erase */ /* the last tfssector... */ if (addrtosector(TFSEND,0,0,&sbase) < 0) return(TFSERR_MEMFAIL); dp = (struct defraghdr *)DefragStateTbl - 1; if ((dp->nda + dp->fhdr.filsize + TFSHDRSIZ) < sbase) { /* Must use spare sector to record this state because this is */ /* the same sector that we were using to keep track of state. */ DefragStateTbl = (ulong *)(TFSSPARE + sparesize - 4); if (setdefragstate(0,ERASING_LAST_SECTOR,verbose)!=TFS_OKAY) return(TFSERR_FLASHFAILURE); TEST_EXIT_POINT(33,-1);erasing_last_sector: if (tfsflasherase(lasttfssector) < 0) { printf("Final sector erase (%d) failed\n",lasttfssector); return(TFSERR_FLASHFAILURE); } TEST_EXIT_POINT(34,-1); } /* All defragmentation is done, so verify sanity of files... */ dummy = tfscheck(verbose); TEST_EXIT_POINT(35,-1); if (tfsflasherase(sparesnum) < 0) { printf("Final spare sector (%d) failed\n",sparesnum); return(TFSERR_FLASHFAILURE); } /* If resetwhendone flag is set, then reset here; else return result of */ /* the file system check. */ if (resetwhendone) monrestart(INITIALIZE); return(dummy);}/* setdefragstate(): The state of the defragmentation process is maintained by a table of longs that is located at the end of the last sector of TFS space. Each long represents the state of a TFS sector. This function simply modifies the bits in one of the longs to maintain the state of a particular sector. Note that the incoming sector number is relative to TFS space, so tfssector=0 does not represent the first sector of flash, it represents the first sector of TFS flash.*/static intsetdefragstate(tfssector,state,verbose)int tfssector, verbose;ulong state;{ if (verbose > 2) printf(" DefragState: %s\n",tfsdefragmsg(state)); if (tfsflashwrite(&DefragStateTbl[tfssector],&state,sizeof(state)) < 0) { printf("setdefragstate(tfssec=%d,state=0x%x) failed\n",tfssector,state); return(TFSERR_FLASHFAILURE); } return(TFS_OKAY);}/* getndaoffset(): This function is used by tfsclean when a file that is being defragmented spans across multiple sectors. Since the defrag header only cotains the sector number of the starting and ending sectors that the file spans across, this is used to retrieve the total offset from the start of the new file (new_destination_address) as each additional sector is defragmented.*/static intgetndaoffset(struct defraghdr *dp,int sec,int *retoffset){ int i, ssize, offset; uchar *addr, *nextbase, *base; offset = 0; sectortoaddr(dp->bsn,0,&nextbase); for(i=dp->bsn;i<sec;i++) { if (addrtosector(nextbase,0,&ssize,&base) < 0) { printf("getndaoffset (dp=0x%x,sector=%d) failed\n",dp,sec); return(TFSERR_MEMFAIL); } if (i == dp->bsn) offset = ssize - dp->bso; else if (i == dp->esn) offset += (ssize - dp->eso); else offset += ssize; nextbase = base+ssize; } *retoffset = offset; return(TFS_OKAY);}/* tfsfixup(): See if a defragmentation was in progress. If yes, finish it; else return.*/static inttfsfixup(verbose)int verbose;{ struct defraghdr *dfhp; struct tfshdr thdr; ulong *statetbl, *spare_statetbl; int sparesize, ftot, i, tfssector, snum;#if DEFRAG_TEST_ENABLED ExitPoint=0; ExitSector=0;#endif if (addrtosector(TFSSPARE,0,&sparesize,0) < 0) return(TFSERR_MEMFAIL); /* Set statetbl to point to what would be the first TFS sector's state */ /* information bitfield (if defrag were in progress). */ statetbl = (ulong *)(TFSEND+1); statetbl -= TFSSECTORCOUNT; /* Set spare_statetbl to point to the last 'long' in the spare sector. */ spare_statetbl = (ulong *)(TFSSPARE + sparesize) - 1; /* Check the end of the TFS space to see if a state table exists, and */ /* also check to see if the last location in the spare sector contains */ /* state. If neither, then defragmentation was not in progress so just */ /* return here. */ if ((*statetbl == (ulong)ERASED32) && (*spare_statetbl == (ulong)ERASED32)) { return(0); } /* Maybe only the last sector (and spare) needs to be erased... */ /* This means that all the files are up-to-date, but the */ /* final stages of sector cleanup didn't finish. */ /* This messiness is caused by the fact that the defragmentation could */ /* have been interrupted when it was erasing the same sector that it */ /* was storing state in. For this sector, the defragmentor uses the */ /* spare sector to store state. */ if (*spare_statetbl == ERASING_LAST_SECTOR) { spare_statetbl -= (TFSSECTORCOUNT-1); if (verbose > 1) { printf("Defrag restart at TFS sector %d\n", tfssector+TFSSECTORCOUNT-1); } _tfsclean(1,spare_statetbl,0,TFSSECTORCOUNT-1,0,verbose); return(0); } if (verbose) printf("File system fixup in progress\n"); if (*statetbl == (ulong)ERASED32) { statetbl = (ulong *)(TFSSPARE + sparesize); statetbl -= TFSSECTORCOUNT; } dfhp = (struct defraghdr *)statetbl - 1; ftot = 0; while(1) { if (dfhp->fhdr.hdrsize == 0xffff) break; thdr = dfhp->fhdr; thdr.next = 0; thdr.hdrcrc = 0; if (crc32(&thdr,TFSHDRSIZ) != dfhp->fhdr.hdrcrc) break; ftot++; dfhp--; } dfhp++; /* If ftot is zero, then we are fixing up an empty file system that */ /* was in the process of being defragmented, so just erase all sectors */ /* and be done... */ if (ftot == 0) { if (verbose) printf("Cleaning up empty TFS...\n"); if (tfsflasheraseall() < 0) printf("TFS erase-all failed\n"); return(TFS_OKAY); } if (verbose) printf("%d files being defragmented\n",ftot); if (addrtosector(TFSSTART,&tfssector,0,0) < 0) return(TFSERR_MEMFAIL); snum = -1; /* Find currently active sector by stepping through the state table */ /* until SECTOR_DEFRAG_INACTIVE state is detected, then step back 1. */ for(i=0;i<TFSSECTORCOUNT;i++) { if (verbose > 1) printf("TFS Sector %d state: 0x%x (%s)\n", tfssector+i, statetbl[i], tfsdefragmsg(statetbl[i])); if ((snum == -1) && (statetbl[i] == SECTOR_DEFRAG_INACTIVE)) snum = i-1; } if (snum == -1) { printf("*****Starting at last sector\n"); snum = TFSSECTORCOUNT-1; if (statetbl[snum] == COPY_HDRS_TO_SPARE) { spare_statetbl = (ulong *)(TFSSPARE + sparesize) - 1; if ((*spare_statetbl == HDRS_IN_SPARE) || (*spare_statetbl == LASTSECTOR_IN_SPARE)) { printf("Adjusting statetbl from 0x%x to 0x%x\n", statetbl,spare_statetbl - (TFSSECTORCOUNT-1)); statetbl = spare_statetbl - (TFSSECTORCOUNT-1); } } } if (verbose > 1) printf("Defrag restart at TFS sector %d\n",tfssector+snum); return(_tfsclean(ftot,statetbl,dfhp,snum,0,verbose));}#if INCLUDE_OLDTFSCLEAN/* oldtfsclean(): Go through the file list and if any deleted files exist, remove them from the flash to eliminate dead space. Copies all valid tfs files to RAM, then erases flash, then reloads what is in RAM back into flash. The function can be told to use a particular starting point in memory or default to APPLICATION_RAMSTART. <<< WARNING >>> THIS FUNCTION SHOULD NOT BE INTERRUPTED*/static intoldtfsclean(verbose,usedefault,tspace,reset)int verbose, reset, usedefault;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -