tfsclean1.c
来自「umon bootloader source code, support mip」· C语言 代码 · 共 2,107 行 · 第 1/5 页
C
2,107 行
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 int
defragNewSectorCrc(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 */
uchar *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,&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);
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 *)dhp->ohdr + fullsize);
new_hspan = defragGetSpantype(activesbase,activesend,
new_hbase,new_hend);
new_dspan = defragGetSpantype(activesbase,activesend,
new_dbase,new_dend);
finfo.fhdr = 1;
fillstat = defragFillFlash(&finfo,new_hspan,&activeaddr,0);
if (fillstat < 0)
return(fillstat);
if (new_hspan == SPANTYPE_BCEL)
break;
finfo.fhdr = 0;
fillstat = defragFillFlash(&finfo,new_dspan,&activeaddr,0);
if (fillstat < 0)
return(fillstat);
if (new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL)
break;
}
sz = activessize - finfo.crcsz;
/* If this is the last sector, then we must not include the space used
* for defrag state storage in the crc calculation.
* We deduct size of CRC table, DHT table and the crc of the DSI space...
*/
if (activesnum == lastsnum) {
sz -= (tdp->sectorcount * sizeof(struct sectorcrc));
sz -= (ftot * DEFRAGHDRSIZ);
sz -= 4;
}
while(sz) {
temp = (finfo.crc ^ 0xff) & 0x000000FFL;
finfo.crc = ((finfo.crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp];
sz--;
}
*newcrc = ~finfo.crc;
return(0);
}
/* defragBuildCrcTable():
* Build the table of sector crcs.
* This consists of a set of CRCs representing each sector
* before defrag starts and after defrag has completed.
* One set for each sector. This table is then used if the
* defrag process is interrupted to determine the state of
* the interrupted defragmentation process.
*/
int
defragBuildCrcTable(TDEV *tdp, struct defraghdr *dht, int verbose)
{
ulong crc;
uchar *sbase;
int i, ssize, dhstsize;
struct sectorcrc *crctbl;
dhstsize = (ulong)(tdp->end+1) - (ulong)dht + 4;
crctbl = defragCrcTable(tdp);
/* The pre-defrag crc table...
* This one's easy because it is simply a crc for each of the current
* sectors.
*/
sbase = (uchar *)tdp->start;
for(i=0;i<tdp->sectorcount;i++) {
if (addrtosector(sbase,0,&ssize,0) < 0)
return(-1);
if (i == tdp->sectorcount-1)
ssize -= dhstsize;
/* The pre-defrag crc: */
crc = crc32(sbase,ssize);
if (defragFwrite(7,(uchar *)&crctbl[i].precrc,
(uchar *)&crc,4) == -1) {
return(-1);
}
/* The post-defrag crc: */
if (defragNewSectorCrc(tdp,dht,i,&crc) < 0)
return(-1);
if (defragFwrite(8,(uchar *)&crctbl[i].postcrc,
(uchar *)&crc,4) == -1) {
return(-1);
}
sbase += ssize;
defragTick(0);
}
return(0);
}
/* _tfsclean():
* This is the front-end of the defragmentation process, following are the
* basic steps of defragmentation...
*
* Build the Defrag State Information (DSI) area:
* 1. Create a table of 32-bit CRCs, two for each sector. One is the CRC
* of the sector prior to beginning defragmentation and the other is
* what will be the CRC of the sector after defragmentation has completed.
* These CRCs are used to help recover from an interrupted defragmentation.
* 2. Create a table of struct defraghdr structures, one for each file in
* TFS that is currently active (not dead).
* 3. Create a CRC of the tables created in steps 1 & 2.
*
* The data created in steps 1-3 is stored at the end of the last sector
* used by TFS for file storage. After this is created, the actual flash
* defragmentation process starts.
*
* File relocation:
* 4. Step through each sector in TFS flash space, process each file whose
* relocated space overlaps with that sector. As each sector is being
* re-built, the original version of that sector is stored in the spare.
*
* End of flash cleanup:
* 5. Run through the remaining, now unsused, space in TFS flash and make
* sure it is erased.
*
* File check:
* 6. Run a check of all of the relocated files to make sure everything is
* still sane.
*
* Defragmentation success depends on some coordination with tfsadd()...
* Whenever a file is added to TFS, tfsadd() must verify that the space
* needed for defrag overhead (defrag state & header tables) will be
* available. Also, tfsadd() must make sure that the defrag overhead will
* always fit into one sector (the sector just prior to the spare).
*/
int
_tfsclean(TDEV *tdp, int restart, int verbose)
{
int dhstsize; /* Size of state table overhead */
int firstsnum; /* Number of first sector in TFS device. */
int lastsnum; /* Number of last sector in TFS device. */
int lastssize; /* Size of last sector in TFS device. */
uchar *lastsbase; /* Base address of last sector in TFS device. */
int sectorcheck; /* Used to verify proper TFS configuration. */
struct defraghdr *dht; /* Pointer to defrag header table. */
int chkstat; /* Result of tfscheck() after defrag is done. */
int ftot; /* Total number of active files in TFS. */
int dtot; /* Total number of deleted files in TFS. */
int fcnt; /* Running file total, used in hdrtbl build. */
TFILE *tfp; /* Misc file pointer */
char *newaddress; /* Used to calculate "new" location of file. */
struct defraghdr defrag; /* Used to build defrag header table. */
int activesnum; /* Sector being worked on restarted defrag. */
struct sectorcrc *crctbl; /* Pointer to table of per-sector crcs. */
int defrag_state;
int sidx, snum;
char *end;
if (TfsCleanEnable < 0)
return(TFSERR_CLEANOFF);
/* If incoming TFS device pointer is NULL, return error
*/
if (!tdp)
return(TFSERR_BADARG);
/* If the 'restart' flag is set, then we only want to do a defrag if
* we determine that one is already in progress; so we have to look at
* the current state of the defrag state table to figure out if a defrag
* was active. If not, just return.
*/
restart = 0; //stone add for debug
if (restart) {
defrag_state = defragGetState(tdp,&activesnum);
switch(defrag_state) {
case SECTOR_DEFRAG_INACTIVE:
case SECTOR_DEFRAG_ABORT_RESTART:
return(TFS_OKAY);
case SCANNING_ACTIVE_SECTOR_1:
case SCANNING_ACTIVE_SECTOR_2:
case SCANNING_ACTIVE_SECTOR_3:
case SCANNING_ACTIVE_SECTOR_4:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?