?? tfs.c
字號:
while(*fstr) { tfp = tfsflgtbl; while(tfp->sdesc) { if (*fstr == tfp->sdesc) { *flag |= tfp->flag; break; } tfp++; } if (!tfp->flag) return(TFSERR_BADFLAG); fstr++; } return(TFS_OKAY);}/* hdrcrc(): * The crc of the file header was originally calculated (in tfsadd()) * with the header crc and next pointer nulled out; so a copy must * be made and these two fields cleared. Also, note that the * TFS_NSTALE and TFS_ACTIVE flags are forced to be set in the copy. * This is done because it is possible that either of these bits may * have been cleared due to other TFS interaction; hence, they need * to be set prior to crc calculation. * Note also that earlier versions of TFS deleted a file by clearing * the entire flags field. This made it impossible to do a header crc * check on a deleted file; deletion has been changed to simply clear * the TFS_ACTIVE bit in the flags, so now a deleted file's header can * can be crc tested by simply forcing the TFS_ACTIVE bit high as was * mentioned above. */ulongtfshdrcrc(TFILE *hdr){ TFILE hdrcpy; hdrcpy = *hdr; hdrcpy.next = 0; hdrcpy.hdrcrc = 0; hdrcpy.flags |= (TFS_NSTALE | TFS_ACTIVE); return(crc32((uchar *)&hdrcpy,TFSHDRSIZ));}/* validtfshdr(): * Return 1 if the header pointed to by the incoming header pointer is valid. * Else return 0. The header crc is calculated based on the hdrcrc * and next members of the structure being zero. * Note that if the file is deleted, then just ignore the crc and return 1. */intvalidtfshdr(TFILE *hdr){ /* A few quick checks... */ if (!hdr || hdr->hdrsize == ERASED16) return(0); if (tfshdrcrc(hdr) == hdr->hdrcrc) { return(1); } else { /* Support transition to new deletion flag method... */ if ((hdr->flags == 0) && tfsOldDelFlagCheckActive) return(1); printf("Bad TFS hdr crc @ 0x%lx\n",(ulong)hdr); return(0); }}/* nextfp(): * Used as a common means of retrieving the next file header pointer. It * does some sanity checks based on the fact that all pointers must fall * within the TFSSTART<->TFSEND memory range and since each file is placed * just after the previous one in linear memory space, fp->next should * always be greater than fp. */TFILE *nextfp(TFILE *fp, TDEV *tdp){ if (!tdp) tdp = gettfsdev(fp); /* Make some basic in-range checks... */ if ((!tdp) || (fp < (TFILE *)tdp->start) || (fp > (TFILE *)tdp->end) || (fp->next < (TFILE *)tdp->start) || (fp->next > (TFILE *)tdp->end) || (fp->next <= fp)) { printf("Bad TFS hdr ptr @ 0x%lx\n",(ulong)fp); return(0); } return(fp->next);}/* tfsflasherased(): * Jump to the point in flash after the last file in TFS, then verify * that all remaining flash that is dedicated to TFS is erased (0xff). * If erased, return 1; else return 0. */inttfsflasherased(TDEV *tdp, int verbose){ ulong *lp; TFILE *tfp; tfp = (TFILE *)tdp->start; while(validtfshdr(tfp)) tfp = nextfp(tfp,tdp); lp = (ulong *)tfp; while (lp < (ulong *)tdp->end) { if (*lp != ERASED32) { if (verbose) printf("End of TFS on %s not erased at 0x%lx\n", tdp->prefix,(ulong)lp); return(0); }#ifdef WATCHDOG_MACRO WATCHDOG_MACRO();#endif lp++; } return(1);}static inttfsftot(TDEV *tdpin){ int ftot; TFILE *tfp; TDEV *tdp; ftot = 0; for (tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) { if (!tdpin || (tdpin == tdp)) { tfp = (TFILE *)tdp->start; while(validtfshdr(tfp)) { if (TFS_FILEEXISTS(tfp)) ftot++; tfp = nextfp(tfp,tdp); } } } return(ftot);}/* tfsmemuse(): * Step through one (or all) TFS devices and tally up various memory usage * totals. See definition of tfsmem structure for more details. * If incoming tdpin pointer is NULL, then tally up for all TFS devices; * otherwise, tally up for only the one device pointed to by tdpin. */inttfsmemuse(TDEV *tdpin, TINFO *tinfo, int verbose){ int devtot; char *cfgerr; TFILE *tfp; TDEV *tdp; /* Start by clearing incoming structure... */ tinfo->pso = 0; tinfo->sos = 0; tinfo->memtot = 0; tinfo->liveftot = 0; tinfo->deadftot = 0; tinfo->livedata = 0; tinfo->deaddata = 0; tinfo->liveovrhd = 0; tinfo->deadovrhd = 0; if (verbose) { printf("TFS Memory Usage...\n "); printf(" name start end spare spsize scnt type\n"); } devtot = 0; for (tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) { if (!tdpin || (tdpin == tdp)) { devtot++; tfp = (TFILE *)tdp->start; cfgerr = (char *)0; /* Do some sanity checks on the configuration... */ if ((tdp->spare >= tdp->start) && (tdp->spare <= tdp->end)) { cfgerr = "spare within storage space"; } if (cfgerr) { printf("Bad %s TFS config: %s.\n",tdp->prefix,cfgerr); } if (verbose) { printf("%10s: 0x%08lx|0x%08lx|0x%08lx|0x%06lx|%4ld|0x%lx\n", tdp->prefix,(ulong)(tdp->start),(ulong)(tdp->end), (ulong)(tdp->spare),tdp->sparesize, tdp->sectorcount,(ulong)(tdp->devinfo)); } tinfo->memtot += ((tdp->end - tdp->start) + 1) + tdp->sparesize; tinfo->pso += (tdp->sectorcount * 4) + 16; tinfo->sos += tdp->sparesize; while(validtfshdr(tfp)) { if (TFS_FILEEXISTS(tfp)) { tinfo->liveftot++; tinfo->livedata += TFS_SIZE(tfp); tinfo->liveovrhd += (TFSHDRSIZ + DEFRAGHDRSIZ); } else { tinfo->deadftot++; tinfo->deaddata += TFS_SIZE(tfp); tinfo->deadovrhd += TFSHDRSIZ; } tfp = nextfp(tfp,tdp); } } } tinfo->memused = tinfo->livedata + tinfo->liveovrhd + tinfo->deaddata + tinfo->deadovrhd + tinfo->pso + tinfo->sos; tinfo->memfree = tinfo->memtot - tinfo->memused; /* Remaining space may not even be big enough to contain the * file overhead, if this is the case, show a remaining space * of zero rather than a negative number... */ tinfo->memfordata = tinfo->memfree - (devtot * (TFSHDRSIZ + DEFRAGHDRSIZ)); if (tinfo->memfordata < 0) tinfo->memfordata = 0; if (verbose) { printf("\n Total memory: %d bytes (used=%d, avail=%d (%d for data)).\n", tinfo->memtot,tinfo->memused,tinfo->memfree, tinfo->memfordata); printf(" Per-device overhead: %d bytes ",tinfo->pso+tinfo->sos); printf("(defrag-state=%d spare-sector=%d).\n",tinfo->pso,tinfo->sos); printf(" File data space: %d bytes (live=%d, dead=%d).\n", tinfo->livedata+tinfo->deaddata, tinfo->livedata,tinfo->deaddata); printf(" File overhead space: %d bytes (live=%d, dead=%d).\n", tinfo->liveovrhd+tinfo->deadovrhd, tinfo->liveovrhd,tinfo->deadovrhd); printf(" File count: %d (live=%d, dead=%d).\n", tinfo->liveftot+tinfo->deadftot,tinfo->liveftot,tinfo->deadftot); printf(" Defrag will release %d bytes\n", tinfo->deadovrhd+tinfo->deaddata); printf("\n"); } return(tinfo->liveftot + tinfo->deadftot);}/* tfscheck(): * Step through each file in a particular device making a few checks... * - First look at the header. If hdrsize is erased, it "should" indicate * the end of the linear list of files. To be anal about it, verify that * the entire header is erased. If it is, we truly are at the end of the * list; otherwise, header error. * - Second, do a crc32 on the header. * - Third, if the file is not deleted, then do a crc32 on the data portion * of the file (if the file is deleted, then it really doesn't matter if * there is a crc32 error on that data). * - Finally, if the header is not corrupted, index to the next pointer and * continue. If the header is corrupt, see if enough information * in the header is valid to allow us to step to the next file. Do this * by calculating where the next pointer should be (using current pointer, * file+header size and mod16 adjustment) and then see if that matches the * value stored in the actual "next" pointer. If yes, go to next file; * else break out of the loop. * * The purpose is to do more sophisticated file system checks than are * done in normal TFS operations. */#define TFS_CORRUPT 1#define HDR_CORRUPT 2#define DATA_CORRUPT 4inttfscheck(TDEV *tdp, int verbose){ int tfscorrupt, filtot; TFILE *fp, *fp1; if (!tdp) return(TFSERR_BADARG); if (verbose) printf("TFS device %s check:\n",tdp->prefix); filtot = tfscorrupt = 0; fp = (TFILE *)tdp->start; while(1) { tfscorrupt &= ~(HDR_CORRUPT | DATA_CORRUPT); /* If hdrsize is ERASED16, then verify that the whole header is * also ERASED16, if yes, we're at the end of the linear list of * files; otherwise, we have a corrupt header. */ if (fp->hdrsize == ERASED16) { int i; ushort *sp; /* If this is right at the edge of the end of the TFS device, * then break with no further checks to this header. */ if ((fp+1) > (TFILE *)tdp->end) break; /* Make sure the entire header is erased... */ sp = (ushort *)fp; for(i=0;i<TFSHDRSIZ;i+=2,sp++) { if (*sp != ERASED16) { if (verbose) printf(" Corrupt hdr @ 0x%lx",(ulong)fp); tfscorrupt = HDR_CORRUPT | TFS_CORRUPT; break; } } if (!(tfscorrupt & HDR_CORRUPT)) break; else goto nextfile; } /* Run a crc check on the header even if file is deleted... */ if (tfshdrcrc(fp) != fp->hdrcrc) { if (verbose) printf(" CRC error in hdr @ 0x%lx\n",(ulong)fp); tfscorrupt = HDR_CORRUPT | TFS_CORRUPT; goto nextfile; } /* If file exists, and it's not IPMOD, run a crc check on data... */ if (TFS_FILEEXISTS(fp) && !(fp->flags & TFS_IPMOD)) { filtot++; if (verbose) printf(" %s...",fp->name); if ((!(fp->flags & TFS_IPMOD)) && (crc32((uchar*)TFS_BASE(fp),fp->filsize) != fp->filcrc)) { if (verbose) printf(" CRC error in data"); tfscorrupt = DATA_CORRUPT | TFS_CORRUPT; } else { if (verbose) printf(" ok"); } } /* Prior to incrementing to the next file pointer, if the header * is corrupted, attempt to salvage the next pointer... * If the value of the next pointer matches what is calculated * from the file size and header size, then assume it is ok * and allow the tfscheck() loop to continue; otherwise break. */nextfile: if (tfscorrupt & HDR_CORRUPT) { if (fp->next) { ulong modnext; modnext = (ulong)((int)(fp+1) + fp->filsize); if (modnext & 0xf) { modnext += 16; modnext &= ~0xf; } if (verbose) printf(" (next ptr "); if (fp->next != (TFILE *)modnext) { if (verbose) printf("damaged)\n"); break; } else { if (verbose) printf("salvaged)"); } } } fp1 = nextfp(fp,tdp); if (!fp1) { tfscorrupt = HDR_CORRUPT | TFS_CORRUPT; break; } if ((verbose) && (TFS_FILEEXISTS(fp) || tfscorrupt)) putchar('\n'); fp = fp1; } tfsflasherased(tdp,verbose); if (tfscorrupt) return(TFSERR_CORRUPT); if (verbose) printf(" PASSED\n"); return (TFS_OKAY);}voidtfsclear(TDEV *tdp){ int i; /* Clear the fileslot[] table indicating that no files are opened. * Only clear the slots applicable to the incoming TDEV pointer. */ for (i = 0; i < TFS_MAXOPEN; i++) { ulong offset; offset = tfsSlots[i].offset; if (offset != (ulong)-1) { if ((tdp == (TDEV *)0) || ((offset >= tdp->start) && (offset <= tdp->end))) tfsSlots[i].offset = -1; } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -