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

📄 ftllite.c

📁 truefs for vxworks, make fs on flash or rom
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Place the logical mapping of the unit */  vol.mappedSectorNo = UNASSIGNED_SECTOR;  vol.logicalUnits[logicalUnitNo] = unit;  return flOK;}/*----------------------------------------------------------------------*//*		           a s s i g n U n i t				*//*									*//* Assigns a logical unit no. to a unit					*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	unit		: Unit to assign				*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus assignUnit(Flare vol,  Unit *unit, UnitNo logicalUnitNo){  LEushort unitNoToWrite;  toLE2(unitNoToWrite,logicalUnitNo);  return flashWrite(&vol,		    physicalBase(&vol,unit) + logicalUnitNoOffset,		    &unitNoToWrite,		    sizeof unitNoToWrite,		    OVERWRITE);}/*----------------------------------------------------------------------*//*		    b e s t U n i t T o T r a n s f e r			*//*									*//* Find best candidate for unit transfer, usually on the basis of which	*//* unit has the most garbage space. A lower wear-leveling info serves	*//* as a tie-breaker. If 'leastUsed' is NOT specified, then the least	*//* wear-leveling info is the only criterion.				*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	leastUsed	: Whether most garbage space is the criterion	*//*                                                                      *//* Returns:                                                             *//*	Best unit to transfer						*//*----------------------------------------------------------------------*/static UnitNo bestUnitToTransfer(Flare vol,  FLBoolean leastUsed){  UnitNo i;  int mostGarbageSectors = 1;  unsigned long int leastWearLevelingInfo = 0xffffffffl;  UnitNo bestUnitSoFar = UNASSIGNED_UNIT_NO;    for(i = 0; i < vol.noOfUnits; i++)    {        Unit *unit = vol.logicalUnits[i];        if(unit && (!leastUsed || (unit->noOfGarbageSectors >= mostGarbageSectors)))        {            UnitHeader FAR0 *unitHeader = mapUnitHeader(&vol,unit,NULL);            if((leastUsed && (unit->noOfGarbageSectors > mostGarbageSectors)) ||               (LE4(unitHeader->wearLevelingInfo) < leastWearLevelingInfo))            {                mostGarbageSectors = unit->noOfGarbageSectors;                leastWearLevelingInfo = LE4(unitHeader->wearLevelingInfo);                bestUnitSoFar = i;            }    }  }  return bestUnitSoFar;}/*----------------------------------------------------------------------*//*		           u n i t T r a n s f e r			*//*									*//* Performs a unit transfer from a selected unit to a tranfer unit.	*//*                                                                      *//* A side effect is to invalidate the map cache (reused as buffer).	*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	toUnit          : Target transfer unit				*//*	fromUnitNo:	: Source logical unit no.			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus unitTransfer(Flare vol,  Unit *toUnit, UnitNo fromUnitNo){    unsigned i;    Unit *fromUnit = vol.logicalUnits[fromUnitNo];    UnitHeader FAR0 *transferUnitHeader = mapUnitHeader(&vol,toUnit,NULL);        if(!verifyFormat(transferUnitHeader) ||      LE2(transferUnitHeader->logicalUnitNo) != UNASSIGNED_UNIT_NO)    /* previous formatting failed or did not complete. 		*/    checkStatus(formatUnit(&vol,toUnit));  /* Should the transfer not complete, the unit is marked to be erased */  checkStatus(assignUnit(&vol,toUnit,MARKED_FOR_ERASE));#ifdef BACKGROUND  vol.mirrorFrom = vol.mirrorTo = physicalBase(&vol,fromUnit);  vol.mirrorOffset = physicalBase(&vol,toUnit) - vol.mirrorFrom;#endif    /* copy the block allocation table and the good sectors */    for(i = 0; i < vol.sectorsPerUnit;)    {        int j;    FLBoolean needToWrite = FALSE;    int firstOffset = allocEntryOffset(&vol,i);    /* Up to 128 bytes of the BAM are processed per loop */    int nEntries = (128 - (firstOffset & 127)) / sizeof(VirtualAddress);    /* We are going to use the Virtual Map cache as our sector buffer in the */    /* transfer, so let's better invalidate the cache first.		   */#ifdef SINGLE_BUFFER    if (buffer.dirty)      return flBufferingError;#endif    buffer.sectorNo = UNASSIGNED_SECTOR;    /* Read some of the BAM */    vol.flash.read(&vol.flash,	       physicalBase(&vol,fromUnit) + firstOffset,	       sectorCopy,	       nEntries * sizeof(VirtualAddress),	       0);    /* Convert garbage entries to free entries */        for(j = 0; j < nEntries && i+j < vol.sectorsPerUnit; j++)        {            unsigned bamSignature = (unsigned) LE4(sectorCopy[j]) & SECTOR_OFFSET_MASK;      if (bamSignature == DATA_SECTOR ||	  bamSignature == REPLACEMENT_PAGE)	needToWrite = TRUE;      else if (bamSignature != FORMAT_SECTOR)	toLE4(sectorCopy[j],FREE_SECTOR);    }        if(needToWrite)        {            FLStatus status;      /* Write new BAM, and copy sectors that need to be copied */      status = flashWrite(&vol,			  physicalBase(&vol,toUnit) + firstOffset,			  sectorCopy,			  nEntries * sizeof(VirtualAddress),                                0);            if(status != flOK)            {#ifdef BACKGROUND	vol.mirrorOffset = 0;	/* no more mirroring */#endif	return status;      }            for(j = 0; j < nEntries && i+j < vol.sectorsPerUnit; j++)            {                unsigned bamSignature = (unsigned) LE4(sectorCopy[j]) & SECTOR_OFFSET_MASK;                if(bamSignature == DATA_SECTOR ||                   bamSignature == REPLACEMENT_PAGE)                { /* a good sector */	  CardAddress sectorOffset = (CardAddress) (i+j) << SECTOR_SIZE_BITS;	  vol.flash.read(&vol.flash,		     physicalBase(&vol,fromUnit) + sectorOffset,		     sectorCopy,SECTOR_SIZE,0);	  status = flashWrite(&vol,			      physicalBase(&vol,toUnit) + sectorOffset,			      sectorCopy,			      SECTOR_SIZE,			      0);                    if(status != flOK)                    {#ifdef BACKGROUND                        vol.mirrorOffset = 0;   /* no more mirroring */#endif	    return status;	  }	  vol.flash.read(&vol.flash,		     physicalBase(&vol,fromUnit) + firstOffset,		     sectorCopy,		     nEntries * sizeof(VirtualAddress),0);	}      }#ifdef BACKGROUND      vol.mirrorTo = vol.mirrorFrom +		     ((CardAddress) (i + nEntries) << SECTOR_SIZE_BITS);      while (flForeground(1) == BG_SUSPEND)	;#endif    }    i += nEntries;  }#ifdef BACKGROUND  vol.mirrorOffset = 0;	/* no more mirroring */#endif  /* Write the new logical unit no. */  checkStatus(assignUnit(&vol,toUnit,fromUnitNo));  /* Mount the new unit in place of old one */    vol.logicalUnits[fromUnitNo] = NULL;    if(mountUnit(&vol,toUnit) == flOK)    {        vol.totalFreeSectors -= fromUnit->noOfFreeSectors;    /* Finally, format the source unit (the new transfer unit) */    vol.transferUnit = fromUnit;    formatUnit(&vol,fromUnit);	/* nothing we can or should do if this fails */  }    else    {        /* Something went wrong */        vol.logicalUnits[fromUnitNo] = fromUnit;    /* reinstate original unit */        /* to avoid corruption, need to erase the failed toUnit.  EAN. */        dbgMsg(DEBUG_LIGHT,"unitTransfer:  mountUnit() failed.  invalidating toUnit %x.\n",(int) toUnit,0,0,0,0,0);        invalidateFormat(&vol,toUnit);        return flGeneralFailure;    }  return flOK;}/*----------------------------------------------------------------------*//*		         g a r b a g e C o l l e c t			*//*									*//* Performs a unit transfer, selecting a unit to transfer and a		*//* transfer unit.                                                       *//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus garbageCollect(Flare vol){  FLStatus status;  UnitNo fromUnitNo;  if (vol.transferUnit == NULL)    return flWriteProtect;	/* Cannot recover space without a spare unit */  fromUnitNo = bestUnitToTransfer(&vol,flRandByte() >= 4);  if (fromUnitNo == UNASSIGNED_UNIT_NO)    return flGeneralFailure;	/* nothing to collect */    /* Find a unit we can transfer to.				*/    status = unitTransfer(&vol,vol.transferUnit,fromUnitNo);    if(status == flWriteFault)    {        int i;        Unit *unit = vol.physicalUnits;        for(i = 0; i < vol.noOfUnits; i++, unit++)        {            if(unit->noOfGarbageSectors == 0 && unit->noOfFreeSectors < 0)            {                if(unitTransfer(&vol,unit,fromUnitNo) == flOK)                    return flOK;  /* found a good one */      }    }  }  return status;}#ifdef BACKGROUND/*----------------------------------------------------------------------*//*		        b g G a r b a g e C o l l e c t			*//*									*//* Entry point for garbage collection in the background.		*//*                                                                      *//* Status is returned in vol.garbageCollectStatus			*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*          								*//* Returns:                                                             *//*	None								*//*----------------------------------------------------------------------*/static void bgGarbageCollect(void * object){  Flare vol = (Flare *)object;  vol.garbageCollectStatus = flIncomplete;  vol.garbageCollectStatus = garbageCollect(&vol);}#endif/*----------------------------------------------------------------------*//*      	            d e f r a g m e n t				*//*									*//* Performs unit transfers to arrange a minimum number of writable	*//* sectors.                                                             *//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorsNeeded	: Minimum required sectors			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/#define GARBAGE_COLLECT_THRESHOLD	20static FLStatus defragment(Flare vol, long FAR2 *sectorsNeeded){    while((long)(vol.totalFreeSectors) < *sectorsNeeded#ifdef BACKGROUND          || vol.totalFreeSectors < GARBAGE_COLLECT_THRESHOLD#endif         )    {        if(vol.badFormat)            return flBadFormat;#ifdef BACKGROUND    if (vol.garbageCollectStatus == flIncomplete)      flBackground(BG_RESUME);    else      flStartBackground(&vol - vols,bgGarbageCollect,&vol);    if (vol.garbageCollectStatus != flOK &&	vol.garbageCollectStatus != flIncomplete)      return vol.garbageCollectStatus;    if (vol.totalFreeSectors >= *sectorsNeeded)      break;  }  if (vol.unitEraseInProgress)    flBackground(BG_SUSPEND);#else    /* if no more units to reclaim, bail out. ALR */    if (flOK != garbageCollect(&vol))    	break;  }#endif  *sectorsNeeded = vol.totalFreeSectors;  return flOK;}/*----------------------------------------------------------------------*//*		    b e s t U n i t T o A l l o c a t e			*//*									*//* Finds the best unit from which to allocate a sector. The unit	*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -