📄 tfsclean.c
字号:
errstate = 56; goto state_error; } if (sectortoaddr(snum_in_spare,&ssize,&sbase) < 0) { errstate = 57; goto state_error; } if (defragFwrite(1,sbase,(uchar *)tdp->spare,ssize) < 0) { errstate = 58; goto state_error; } if (defragEraseSpare(tdp) < 0) { errstate = 59; goto state_error; } return(SCANNING_ACTIVE_SECTOR_5); } /* If we got here, then we are confused, so don't do any defrag * continuation... */ errstate = 90;state_error: printf("DEFRAG_STATE_ERROR: #%d.\n",errstate); return(SECTOR_DEFRAG_INACTIVE);}/* inSector(): * We are trying to figure out if the address space that we want to copy * from is within the active sector. If it is, then we need to adjust * our pointers so that we retrieve the at least some of data from the * spare. * If the range specified by 'i_base' and 'i_size' overlays (in any way) * the address space used by the sector specified by 'snum', * then return the address in the spare and the size of the overlay. */static intinSector(TDEV *tdp,int snum,uchar *i_base,int i_size,uchar **saddr,int *ovlysz){ int s_size; uchar *s_base, *s_end, *i_end; /* Retrieve information about the sector: */ if (sectortoaddr(snum,&s_size,&s_base) == -1) return(TFSERR_MEMFAIL); i_end = i_base + i_size; s_end = s_base + s_size; if ((i_end < s_base) || (i_base > s_end)) { *ovlysz = 0; return(0); } if (i_base < s_base) { if (i_end > s_end) { *ovlysz = s_size; } else { *ovlysz = (i_size - (s_base - i_base)); } *saddr = (uchar *)tdp->spare; } else { if (i_end > s_end) { *ovlysz = (i_size - (i_end - s_end)); } else { *ovlysz = i_size; } *saddr = (uchar *)tdp->spare + (i_base - s_base); } return(0);}/* struct fillinfo & FILLMODE definitions: * Structure used by the "Fill" functions below. */#define FILLMODE_FWRITE 1 /* Do the flash write */#define FILLMODE_SPAREOVERLAP 2 /* Determine if there is SPARE overlap */#define FILLMODE_CRCONLY 3 /* Calculate a 32-bit crc on the data */struct fillinfo { struct defraghdr *dhp; /* pointer to defrag header table */ TDEV *tdp; /* pointer to TFS device */ ulong crc; /* used in FILLMODE_CRCONLY mode */ int crcsz; /* size of crc calculation */ int fhdr; /* set if we're working on a file header */ int asnum; /* the active sector */ int mode; /* see FILLMODE_xxx definitions */};/* defragFillFlash(): * This function is called by the defragFillActiveSector() function * below. It covers the four different cases of a file spanning over * the active sector, plus it deals with the possibility that the source * of the file data may be the same sector as the active one (meaning that * the source is taken from the spare). It is within this function that * the active sector is actually modified and it assumes that the portion * of the active sector to be written to is already erased. * * * SPANTYPE_BCEC: * In this case, the file starts in a sector prior to the currently active * sector and ends in the active sector... * -----------|----------|----------|----------|---------|---------|---------- * | | | | | | | | * | | |<-active->| | | | SPARE | * | | | sector | | | | SECTOR | * | | | | | | | | * | | | newfile | | | | | * | | | |<-->| | | | | | * -----------|----------|----------|----------|---------|---------|---------- * * * SPANTYPE_BPEC: * In this case, the file starts in a sector prior to the currently active * sector and ends in the active sector... * -----------|----------|----------|----------|---------|---------|---------- * | | | | | | | | * | | | |<-active->| | | SPARE | * | | | | sector | | | SECTOR | * | | | | | | | | * | | |<----newfile----->| | | | | * | | | | | | | | * -----------|----------|----------|----------|---------|---------|---------- * * * SPANTYPE_BPEL: * In this case, the file starts in some sector prior to the currently * active sector and ends in some sector after the currently active * sector... * -----------|----------|----------|----------|---------|---------|---------- * | | | | | | | | * | | |<-active->| | | | SPARE | * | | | sector | | | | SECTOR | * | | | | | | | | * | |<---------- newfile------------------->| | | | * | | | | | | | | * -----------|----------|----------|----------|---------|---------|---------- * * * SPANTYPE_BCEL: * In this case, the file starts in the active sector and ends in * a later sector. * -----------|----------|----------|----------|---------|---------|---------- * | | | | | | | | * | |<-active->| | | | | SPARE | * | | sector | | | | | SECTOR | * | | | | | | | | * | | |<----newfile----->| | | | | * | | ****| | | | | | * -----------|----------|----------|----------|---------|---------|---------- */static intdefragFillFlash(struct fillinfo *fip,int spantype,char **activeaddr,int verbose){ char *hp; TFILE nfhdr; struct defraghdr *dhp; int ohdroffset, nhdroffset; uchar *ovly, *src, *activesbase; int ovlysz, srcsz, activessize; src = 0; srcsz = 0; nhdroffset = ohdroffset = 0; dhp = fip->dhp; if (verbose >= 2) { printf(" defragFillFlash %s %s\n",fip->fhdr ? "hdr" : "dat", defragGetSpantypeStr(spantype)); } if (spantype == SPANTYPE_BCEC) { if (fip->fhdr) { src = (uchar *)dhp->ohdr; srcsz = TFSHDRSIZ; } else { src = (uchar *)dhp->ohdr+TFSHDRSIZ; srcsz = dhp->filsize; } } else if (spantype == SPANTYPE_BPEC) { if (fip->fhdr) { /* Calculate the offset into the header at which point a * sector boundary occurs. Do this for both the old (before * defrag relocation) and new (after defrag relocation) * location of the header. */ nhdroffset = TFSHDRSIZ - (dhp->neso - dhp->filsize); ohdroffset = TFSHDRSIZ - (dhp->oeso - dhp->filsize); srcsz = dhp->oeso - dhp->filsize + (ohdroffset - nhdroffset); src = (uchar *)dhp->ohdr + nhdroffset; } else { src = (uchar *)dhp->ohdr + TFSHDRSIZ + (dhp->filsize - dhp->neso); srcsz = dhp->neso; } } else if (spantype == SPANTYPE_BCEL) { if (sectortoaddr(fip->asnum,&activessize,&activesbase) == -1) return(TFSERR_MEMFAIL); if (fip->fhdr) { src = (uchar *)dhp->ohdr; } else { src = (uchar *)dhp->ohdr+TFSHDRSIZ; } srcsz = (activesbase + activessize) - (uchar *)*activeaddr; } else if (spantype == SPANTYPE_BPEL) { if (sectortoaddr(fip->asnum,&activessize,0) == -1) return(TFSERR_MEMFAIL); if (fip->fhdr) { src = (uchar *)dhp->ohdr; } else { src = (uchar *)dhp->ohdr+TFSHDRSIZ; } src += ((*activeaddr - dhp->nda) - TFSHDRSIZ); srcsz = activessize; } else { return(0); } /* Determine if any portion of the source was part of the sector that * is now the active sector.. If yes (ovlysz > 0), then we must * deal with the fact that some (or all) of the fill source is in the * spare sector... */ if (inSector(fip->tdp,fip->asnum,src,srcsz,&ovly,&ovlysz) < 0) return(TFSERR_MEMFAIL); /* If the mode is not FILLMODE_FWRITE, then we don't do any of the * flash operations. We are in this function only to determine * if we need to copy the active sector to the spare prior to * starting the modification of the active sector. */ if (fip->mode == FILLMODE_FWRITE) { if (fip->fhdr) { hp = (char *)&nfhdr; if (ovlysz) { memcpy(hp+nhdroffset,ovly,ovlysz); if (ovlysz != srcsz) { memcpy(hp+nhdroffset+ovlysz,(char *)src+ovlysz, srcsz-ovlysz); } } else { nfhdr = *dhp->ohdr; } nfhdr.next = dhp->nextfile; if (defragFwrite(2,*activeaddr,hp+nhdroffset,srcsz) == -1) return(TFSERR_FLASHFAILURE); } else { if (ovlysz) { if (defragFwrite(3,*activeaddr,(char *)ovly,ovlysz) == -1) return(TFSERR_FLASHFAILURE); if (ovlysz != srcsz) { if (defragFwrite(4,*activeaddr+ovlysz,(char *)src+ovlysz, srcsz-ovlysz) == -1) return(TFSERR_FLASHFAILURE); } } else { if (defragFwrite(5,*activeaddr,(char *)src,srcsz) == -1) return(TFSERR_FLASHFAILURE); } } } else if (fip->mode == FILLMODE_CRCONLY) { register uchar *bp; int sz, temp; if (fip->fhdr) { hp = (char *)&nfhdr; nfhdr = *dhp->ohdr; nfhdr.next = dhp->nextfile; bp = hp + nhdroffset; } else { bp = (uchar *)src; } sz = srcsz; fip->crcsz += sz; while(sz) { temp = (fip->crc ^ *bp++) & 0x000000FFL; fip->crc = ((fip->crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; sz--; } } *activeaddr += srcsz; if ((spantype == SPANTYPE_BCEC || spantype == SPANTYPE_BPEC) && (!fip->fhdr) && ((ulong)*activeaddr & 0xf)) { int sz, temp, modfixsize; modfixsize = (TFS_FSIZEMOD - ((ulong)*activeaddr & (TFS_FSIZEMOD-1))); *activeaddr += modfixsize; if (fip->mode == FILLMODE_CRCONLY) { sz = modfixsize; fip->crcsz += sz; while(sz) { temp = (fip->crc ^ 0xff) & 0x000000FFL; fip->crc = ((fip->crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; sz--; } } } /* Return ovlysz so that the caller will know if this function * needed the spare sector. This is used in the "mode = SPARE_OVERLAP" * pass of defragFillActiveSector(). */ return(ovlysz);}/* defragFillActiveSector(): * This and defragFillFlash() are the workhorses of the tfsclean() function. * The bulk of this function is used to determine if we need to do anything * to the active sector and if so, do we need to copy the active sector to * the spare prior to erasing it. * The first loop in this function determines whether we need to do anything * at all with this sector (it may not be touched by the defragmentation). * The second loop determines if we have to copy the active sector to the * spare prior to erasing the active sector. * The final loop in this function does the call to defragFillFlash() * to do the actual flash writes. */static intdefragFillActiveSector(TDEV *tdp, int ftot, int snum, int verbose){ 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 *sdhp;/* pointer into defrag hdr table in spare */ 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 noreloctot; /* number of files spanning the active sector */ /* that do not have to be relocated */ int tmptot; /* temps used for the "SPARE_OVERLAP" mode */ char *tmpactiveaddr; struct defraghdr *tmpdhp; struct fillinfo finfo; struct sectorcrc *crctbl; int lastsnum, tot; int copytospare; int lastfileisnotrelocated; /* Retrieve number of first TFS sector: */ if (addrtosector((char *)tdp->start,&firstsnum,0,0) < 0) return(TFSERR_MEMFAIL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -