📄 tfsclean.c
字号:
(ulong)(defrag.nda),(ulong)(defrag.fdf));
}
size = TFS_SIZE(tfp) + TFSHDRSIZ;
if (size & 0xf) {
size += 16;
size &= ~0xf;
}
newaddress += size;
defrag.fhdr.next = (TFILE *)newaddress;
#if TFS_DEBUG
if (verbose > 3) {
printf(" fhdr.hdrsize=0x%x\n",defrag.fhdr.hdrsize);
printf(" fhdr.hdrvrsn=0x%x\n",defrag.fhdr.hdrvrsn);
printf(" fhdr.filsize=0x%x\n",defrag.fhdr.filsize);
printf(" fhdr.flags=0x%x\n",defrag.fhdr.flags);
printf(" fhdr.filcrc=0x%x\n",defrag.fhdr.filcrc);
printf(" fhdr.hdrcrc=0x%x\n",defrag.fhdr.hdrcrc);
printf(" fhdr.modtime=0x%x\n",defrag.fhdr.modtime);
printf(" fhdr.next=0x%x\n",defrag.fhdr.next);
}
#endif
if (tfsflashwrite((ulong *)(&defraghdrtbl[fcnt]),
(ulong *)(&defrag),DEFRAGHDRSIZ) == -1) {
printf("Flash write failed during header build\n");
return(TFSERR_FLASHFAILURE);
}
fcnt++;
TEST_EXIT_POINT(3,-1);
}
tfp = nextfp(tfp,tdp);
}
if (fcnt != ftot)
printf("\007 fcnt != ftot!\n");
TEST_EXIT_POINT(4,-1);
/* Mark the defragmentation state table to indicate that the */
/* defragmentation headers have been constructed. */
if (setdefragstate(0,HEADER_TABLE_READY,verbose) != TFS_OKAY)
return(TFSERR_FLASHFAILURE);
hdr_table_ready:
/* For each sector dedicated to TFS, do the following... */
if (verbose) {
if (verbose > 1)
printf("\nPER-SECTOR DEFRAGMENTATION STEPS:\n");
printf("Defragmenting sectors %d - %d...\n",
firsttfssector,lasttfssector);
}
sidx = 0;
for(tfssector=firsttfssector;tfssector<=lasttfssector;tfssector++,sidx++) {
if (verbose) {
printf(" Sector %3d (base=0x%lx, size=%d)...\n",
tfssector,(ulong)sbase,ssize);
}
/* If the current sector is prior to the first sector that contains */
/* a file that has been removed, then this sector will not change, */
/* so we can skip over it... */
dp = defraghdrtbl;
if (dp->fdf > sbase+ssize) {
if (verbose > 2) {
printf(" no change");
if (verbose > 3)
printf(" (0x%lx > 0x%lx+0x%x",
(ulong)(dp->fdf),(ulong)sbase,ssize);
printf(".\n");
}
goto sector_defrag_skip;
}
/* Look to see if this sector has any valid file data in it. */
/* If not, continue with next sector. */
dp = defraghdrtbl;
while (dp < (struct defraghdr *)DefragStateTbl) {
if ((tfssector >= dp->bsn) && (tfssector <= dp->esn))
break;
dp++;
}
if (dp >= (struct defraghdr *)DefragStateTbl) {
TEST_EXIT_POINT(5,tfssector);
if (setdefragstate(sidx,ERASING_DEAD_SECTOR,verbose) != TFS_OKAY)
return(TFSERR_FLASHFAILURE);
erasing_dead_sector:
TEST_EXIT_POINT(6,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(7,tfssector);
sbase += ssize;
if (addrtosector(sbase,0,&ssize,0) < 0)
return(TFSERR_MEMFAIL);
continue;
}
/* If this is the last file sector, we must copy the defrag
* tables to the end of the SPARE sector.
*/
if (tfssector == lasttfssector) {
ulong *newdefragstatetbl; /* new defrag table pointers */
struct defraghdr *newdefraghdrtbl;
TEST_EXIT_POINT(8,tfssector);
if (setdefragstate(sidx,COPY_HDRS_TO_SPARE,verbose) != TFS_OKAY)
return(TFSERR_FLASHFAILURE);
TEST_EXIT_POINT(9,tfssector);
copy_hdrs_to_spare:
newdefragstatetbl = (ulong *)(tdp->spare+tdp->sparesize);
newdefragstatetbl -= tdp->sectorcount;
newdefraghdrtbl = (struct defraghdr *)(newdefragstatetbl) - ftot;
/* Copy defrag tables to end of SPARE sector...
* Note that tfsadd() guarantees that the size of the defrag
* overhead will not exceed the size of the spare sector.
*/
if (tfsflashwrite((ulong *)newdefraghdrtbl,(ulong *)defraghdrtbl,
tdp->end-(int)defraghdrtbl+1) < 0) {
printf("Flash defraghdrtbl write failed\n");
return(TFSERR_FLASHFAILURE);
}
DefragStateTbl = (ulong *)(tdp->spare+tdp->sparesize);
DefragStateTbl -= tdp->sectorcount;
TEST_EXIT_POINT(10,tfssector);
if (setdefragstate(sidx,HDRS_IN_SPARE,verbose)!=TFS_OKAY)
return(TFSERR_FLASHFAILURE);
hdrs_in_spare:
DefragStateTbl = (ulong *)(tdp->spare+tdp->sparesize);
DefragStateTbl -= tdp->sectorcount;
TEST_EXIT_POINT(11,tfssector);
/* Copy remainder of last ellibible file sector plus all
* additional sectors spanned by the defrag overhead to the
* SPARE sector...
*/
if (tfsflashwrite((ulong *)(tdp->spare),(ulong *)sbase,
(char *)defraghdrtbl-sbase) < 0) {
printf("Flash final sector (%d) copy failed\n",tfssector);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(12,tfssector);
if (setdefragstate(sidx,LASTSECTOR_IN_SPARE,verbose)!=TFS_OKAY)
return(TFSERR_FLASHFAILURE);
lastsector_in_spare:
defraghdrtbl = (struct defraghdr *)(DefragStateTbl) - ftot;
TEST_EXIT_POINT(13,tfssector);
}
else {
TEST_EXIT_POINT(14,tfssector);
/* Copy TFS sector to SPARE, then update state. */
if (tfsflashwrite((ulong *)(tdp->spare),(ulong *)sbase,ssize) < 0) {
printf("Flash sector %d copy failed\n",tfssector);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(15,tfssector);
if (setdefragstate(sidx,SECTOR_COPIED_TO_SPARE,verbose)!=TFS_OKAY)
return(TFSERR_FLASHFAILURE);
TEST_EXIT_POINT(16,tfssector);
}
sector_copied_to_spare:
TEST_EXIT_POINT(17,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(18,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 a partial header copy was started, in the previous sector
* then finish the copy of the header here...
*/
if (PHC_IS_STARTED(dp->phc)) {
int phc;
/* Copy remainder of the header from defraghdrtbl[]... */
if (verbose > 1)
printf(" Completing phc (dp=0x%lx)\n",(ulong)dp);
phc = GET_PHC_VALUE(dp->phc);
if (tfsflashwrite((ulong *)(dp->nda+phc),
(ulong *)(((int)(&dp->fhdr))+phc),TFSHDRSIZ-phc) == -1) {
printf("Phc end (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
/* Now that the second half of the partial hdr copy is done */
/* clear the upper bit of phc in the defraghdrtbl[]... */
phc = SET_PHC_COPIED(dp->phc);
if (tfsflashwrite(&dp->phc,(ulong *)(&phc),sizeof(int)) == -1) {
printf("Phc clear1 (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(19,tfssector);
}
if (dp->bsn == dp->esn) { /* Whole file is in SPARE */
if (verbose > 1)
printf(" Complete_copy (nda=0x%lx,nxt=0x%lx,size=%ld)\n",
(ulong)(dp->nda),
(ulong)(dp->fhdr.next),dp->fhdr.filsize+TFSHDRSIZ);
TEST_EXIT_POINT(20,tfssector);
/* Copy the header from defraghdrtbl[]... */
if (tfsflashwrite((ulong *)(dp->nda),(ulong *)(&dp->fhdr),
TFSHDRSIZ) == -1) {
printf("Sector-update1 (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(21,tfssector);
/* Copy the file data from SPARE... */
if (tfsflashwrite((ulong *)(dp->nda+TFSHDRSIZ),
(ulong *)(tdp->spare+dp->bso+TFSHDRSIZ),
dp->fhdr.filsize) == -1) {
printf("Sector-update2 (dp=0x%lx) failed\n",(ulong)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%lx,nxt=0x%lx,size=%d)\n",
(ulong)(dp->nda),
(ulong)(dp->fhdr.next),fsize+TFSHDRSIZ);
/* If fsize is less than 0, then only a portion of the
* file's header is going to be copied...
*/
if (fsize < 0) {
int phc;
phc = fsize+TFSHDRSIZ;
if (verbose > 1)
printf(" Starting phc (dp=0x%lx)\n",(ulong)dp);
/* Copy portion of the header from defraghdrtbl[]... */
if (tfsflashwrite((ulong *)(dp->nda),(ulong *)(&dp->fhdr),
phc) == -1) {
printf("Sector-update3 (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(22,tfssector);
/* Indicate in the defrag header that only a partial
* header copy was done. The phc entry in the defrag
* header will contain the size of the portion of the
* header that was copied ORed with TFS_PHCSTARTED.
* This upper bit is set so that it can be used as an
* indication that the other half of the header must
* be copied.
*/
phc = SET_PHC_STARTED(phc);
if (tfsflashwrite(&dp->phc,(ulong *)(&phc),
sizeof(int)) == -1) {
printf("Phc begin (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(23,tfssector);
}
else {
TEST_EXIT_POINT(24,tfssector);
/* Copy the header from defraghdrtbl[]... */
if (tfsflashwrite((ulong *)(dp->nda),(ulong *)(&dp->fhdr),
TFSHDRSIZ) == -1) {
printf("Sector-update4 (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(25,tfssector);
if (tfsflashwrite((ulong *)(dp->nda+TFSHDRSIZ),
(ulong *)(tdp->spare+dp->bso+TFSHDRSIZ),fsize) == -1) {
printf("Sector-update5 (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
TEST_EXIT_POINT(26,tfssector);
}
}
else if (tfssector == dp->esn) { /* End of file is in SPARE */
int offset, phc=0;
if (getndaoffset(dp,tfssector,&offset) == -1)
return(TFSERR_FLASHFAILURE);
if (PHC_IS_COPIED(dp->phc))
phc = TFSHDRSIZ - GET_PHC_VALUE(dp->phc);
if (verbose > 1) {
printf(" Endof_copy (nda offset=0x%x, size=%d",
offset,dp->eso);
if (phc)
printf(", phc=0x%x)\n",phc);
else
printf(")\n");
}
TEST_EXIT_POINT(27,tfssector);
if (dp->eso > phc) {
if (PHC_IS_COPIED(dp->phc)) {
ulong phctmp;
if (tfsflashwrite((ulong *)(dp->nda+offset+phc),
(ulong *)(tdp->spare+phc),dp->eso-phc) == -1) {
printf("Sector-update6 (dp=0x%lx) failed\n",
(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
phctmp = SET_PHC_DONE(dp->phc);
if (tfsflashwrite(&dp->phc,&phctmp,sizeof(int)) == -1) {
printf("Phc clear2 (dp=0x%lx) failed\n",(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
}
else {
if (tfsflashwrite((ulong *)(dp->nda+offset),
(ulong *)(tdp->spare),dp->eso) == -1) {
printf("Sector-update7 (dp=0x%lx) failed\n",
(ulong)dp);
return(TFSERR_FLASHFAILURE);
}
}
}
TEST_EXIT_POINT(28,tfssector);
}
else { /* Middle of file is in SPARE */
int offset, phc=0;
if (getndaoffset(dp,tfssector,&offset) == -1)
return(TFSERR_FLASHFAILURE);
if (PHC_IS_COPIED(dp->phc))
phc = TFSHDRSIZ - GET_PHC_VALUE(dp->phc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -