⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfsclean.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -