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

📄 ftllite.c

📁 该程序是一个tffs文件系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
{  unsigned iSector;  LEulong FAR0 *blockAllocMap;  UnitHeader FAR0 *unitHeader;  Unit *allocationUnit = NULL;  LogicalSectorNo previousSectorAddress =	 sectorNo > 0 ? virtual2Logical(&vol,sectorNo - 1) : UNASSIGNED_SECTOR;#ifdef DEBUG_PRINT  DEBUG_PRINT("Debug: findFreeSector -> %d !!\n", sectorNo);#endif  if (previousSectorAddress != UNASSIGNED_SECTOR &&      previousSectorAddress != DELETED_SECTOR) {    allocationUnit =	vol.logicalUnits[previousSectorAddress >> (vol.unitSizeBits - SECTOR_SIZE_BITS)];    if (allocationUnit->noOfFreeSectors > 0) {      unsigned int sectorIndex = ((unsigned) previousSectorAddress & (vol.sectorsPerUnit - 1)) + 1;      LEulong FAR0 *nextSectorAddress =	   (LEulong FAR0 *) vol.flash.map(&vol.flash,				     physicalBase(&vol,allocationUnit) +                                          allocEntryOffset(&vol, sectorIndex),				     sizeof(VirtualAddress));      if (sectorIndex < vol.sectorsPerUnit && LE4(*nextSectorAddress) == FREE_SECTOR) {	/* can write sequentially */	*newAddress = previousSectorAddress + 1;	return flOK;      }    }    else      allocationUnit = NULL;	/* no space here, try elsewhere */  }  if (allocationUnit == NULL)    allocationUnit = bestUnitToAllocate(&vol);  if (allocationUnit == NULL)	/* No ? then all is lost */ {#ifdef DEBUG_PRINT      DEBUG_PRINT("Debug: findFreeSector -> Unable to find free sector!!\n");#endif    return flGeneralFailure;  }  unitHeader = mapUnitHeader(&vol,allocationUnit,&blockAllocMap);  for (iSector = vol.unitHeaderSectors; iSector < vol.sectorsPerUnit; iSector++) {    if (LE4(blockAllocMap[iSector]) == FREE_SECTOR) {      *newAddress = ((LogicalSectorNo) (LE2(unitHeader->logicalUnitNo)) << (vol.unitSizeBits - SECTOR_SIZE_BITS)) +		    iSector;      return flOK;    }  }#ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: findFreeSector -> Problem marking allocation map!!\n");#endif  return flGeneralFailure;	/* what are we doing here ? */}/*----------------------------------------------------------------------*//*		           m a r k A l l o c M a p			*//*									*//* Writes a new value to a BAM entry.					*//*                                                                      *//* This routine also updates the free & garbage sector counts.		*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorAddress	: Logical sector no. whose BAM entry to mark	*//*	allocMapEntry	: New BAM entry value				*//*	overwrite	: Whether we are overwriting some old value	*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus markAllocMap(Flare vol,			   LogicalSectorNo sectorAddress,			   VirtualAddress allocMapEntry,			   FLBoolean overwrite){  UnitNo unitNo = (UnitNo) (sectorAddress >> (vol.unitSizeBits - SECTOR_SIZE_BITS));  Unit *unit = vol.logicalUnits[unitNo];  int sectorInUnit = (unsigned) sectorAddress & (vol.sectorsPerUnit - 1);  LEulong bamEntry;  if (unitNo >= vol.noOfUnits - vol.noOfTransferUnits)    return flGeneralFailure;  if (allocMapEntry == GARBAGE_SECTOR)    unit->noOfGarbageSectors++;  else if (!overwrite) {    unit->noOfFreeSectors--;    vol.totalFreeSectors--;  }  toLE4(bamEntry,allocMapEntry);  return flashWrite(&vol,		    physicalBase(&vol,unit) + allocEntryOffset(&vol,sectorInUnit),		    &bamEntry,		    sizeof bamEntry,		    overwrite);}/*----------------------------------------------------------------------*//*      	      d e l e t e L o g i c a l S e c t o r		*//*									*//* Marks a logical sector as deleted.					*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorAddress	: Logical sector no. to delete			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus deleteLogicalSector(Flare vol,  LogicalSectorNo sectorAddress){  if (sectorAddress == UNASSIGNED_SECTOR ||      sectorAddress == DELETED_SECTOR)    return flOK;  return markAllocMap(&vol,sectorAddress,GARBAGE_SECTOR,TRUE);}/* forward definition */static FLStatus setVirtualMap(Flare vol,			    VirtualSectorNo sectorNo,			    LogicalSectorNo newAddress);/*----------------------------------------------------------------------*//*      	     a l l o c a t e A n d W r i t e S e c t o r	*//*									*//* Allocates a sector or replacement page and (optionally) writes it.	*//*                                                                      *//* An allocated replacement page also becomes the active replacement 	*//* page.								*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Virtual sector no. to write			*//*	fromAddress	: Address of sector data. If NULL, sector is	*//*			  not written.					*//*	replacementPage	: This is a replacement page sector.		*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus allocateAndWriteSector(Flare vol,				     VirtualSectorNo sectorNo,				     void FAR1 *fromAddress,				     FLBoolean replacementPage){  FLStatus status;  LogicalSectorNo sectorAddress;  VirtualAddress bamEntry =	((VirtualAddress) sectorNo - vol.noOfPages) << SECTOR_SIZE_BITS;  long sectorsNeeded = 1;#ifdef DEBUG_PRINT  DEBUG_PRINT("Debug: calling defrgment routine!!\n");#endif  checkStatus(defragment(&vol,&sectorsNeeded));  /* Organize a free sector */#ifdef DEBUG_PRINT  DEBUG_PRINT("Debug: calling routine findFreeSector !!\n");#endif  checkStatus(findFreeSector(&vol,sectorNo,&sectorAddress));  if (replacementPage)    bamEntry |= REPLACEMENT_PAGE;  else    bamEntry |= DATA_SECTOR;  status = markAllocMap(&vol,			sectorAddress,			sectorNo < vol.directAddressingSectors ?			  ALLOCATED_SECTOR : bamEntry,			FALSE);  if (status == flOK && fromAddress)    status = flashWrite(&vol,			logical2Physical(&vol,sectorAddress),			fromAddress,			SECTOR_SIZE,			0);  if (sectorNo < vol.directAddressingSectors && status == flOK)    status = markAllocMap(&vol,			  sectorAddress,			  bamEntry,			  TRUE);  if (status == flOK)    if (replacementPage) {      vol.replacementPageAddress = sectorAddress;      vol.replacementPageNo = sectorNo;    }    else      status = setVirtualMap(&vol,sectorNo,sectorAddress);  if (status != flOK)    status = markAllocMap(&vol,sectorAddress,GARBAGE_SECTOR,TRUE);#ifdef DEBUG_PRINT  if (status != flOK)  DEBUG_PRINT("Debug: Bad status code at Allocate and Write sector !\n");  DEBUG_PRINT("Debug: MarkAllocMap returned %d !\n", status);#endif  return status;}/*----------------------------------------------------------------------*//*      	     c l o s e R e p l a c e m e n t P a g e		*//*									*//* Closes the replacement page by merging it with the primary page.	*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus closeReplacementPage(Flare vol){  FLStatus status;#ifdef SINGLE_BUFFER  int i;  LogicalSectorNo nextReplacementPageAddress = vol.replacementPageAddress;  VirtualSectorNo firstSectorNo =	((VirtualSectorNo) vol.replacementPageNo << (PAGE_SIZE_BITS - SECTOR_SIZE_BITS)) +	vol.noOfPages;pageRetry:  for (i = 0; i < ADDRESSES_PER_SECTOR; i++) {    LogicalSectorNo logicalSectorNo = virtual2Logical(&vol,firstSectorNo + i);    LEulong entryToWrite;    toLE4(entryToWrite,logicalSectorNo == UNASSIGNED_SECTOR ?		       UNASSIGNED_ADDRESS :		       (LogicalAddress) logicalSectorNo << SECTOR_SIZE_BITS);    if (flashWrite(&vol,		   logical2Physical(&vol,nextReplacementPageAddress) +			i * sizeof(LogicalAddress),		   &entryToWrite,		   sizeof entryToWrite,		   OVERWRITE) != flOK)      break;  }  if (i < ADDRESSES_PER_SECTOR &&      nextReplacementPageAddress == vol.replacementPageAddress) {    /* Uh oh. Trouble. Let's replace this replacement page. */    LogicalSectorNo prevReplacementPageAddress = vol.replacementPageAddress;    checkStatus(allocateAndWriteSector(&vol,vol.replacementPageNo,NULL,TRUE));    nextReplacementPageAddress = vol.replacementPageAddress;    vol.replacementPageAddress = prevReplacementPageAddress;    goto pageRetry;  }  if (nextReplacementPageAddress != vol.replacementPageAddress) {    LogicalSectorNo prevReplacementPageAddress = vol.replacementPageAddress;    vol.replacementPageAddress = nextReplacementPageAddress;    checkStatus(deleteLogicalSector(&vol,prevReplacementPageAddress));  }#else  setupMapCache(&vol,vol.replacementPageNo);	/* read replacement page into map cache */  status = flashWrite(&vol,		      logical2Physical(&vol,vol.replacementPageAddress),		      mapCache,SECTOR_SIZE,OVERWRITE);  if (status != flOK) {    /* Uh oh. Trouble. Let's replace this replacement page. */    LogicalSectorNo prevReplacementPageAddress = vol.replacementPageAddress;    checkStatus(allocateAndWriteSector(&vol,vol.replacementPageNo,mapCache,TRUE));    checkStatus(deleteLogicalSector(&vol,prevReplacementPageAddress));  }#endif  checkStatus(setVirtualMap(&vol,vol.replacementPageNo,vol.replacementPageAddress));  checkStatus(markAllocMap(&vol,			   vol.replacementPageAddress,			   (((VirtualAddress) vol.replacementPageNo - vol.noOfPages)				<< SECTOR_SIZE_BITS) | DATA_SECTOR,			   TRUE));  vol.replacementPageNo = UNASSIGNED_SECTOR;  return flOK;}/*----------------------------------------------------------------------*//*      	          s e t V i r t u a l M a p			*//*									*//* Changes an entry in the virtual map					*//*									*//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	sectorNo	: Virtual sector no. whose entry is changed.	*//*	newAddress	: Logical sector no. to assign in Virtual Map.	*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, failed otherwise		*//*----------------------------------------------------------------------*/static FLStatus setVirtualMap(Flare vol,			    VirtualSectorNo sectorNo,			    LogicalSectorNo newAddress){  unsigned pageNo;  int sectorInPage;  CardAddress virtualMapEntryAddress;  LEulong addressToWrite;  LogicalAddress oldAddress;  LogicalSectorNo updatedPage;  vol.mappedSectorNo = UNASSIGNED_SECTOR;  if (sectorNo < vol.directAddressingSectors) {    checkStatus(deleteLogicalSector(&vol,vol.pageTable[sectorNo]));    vol.pageTable[sectorNo] = newAddress;    return flOK;  }  sectorNo -= vol.noOfPages;  pageNo = sectorNo >> (PAGE_SIZE_BITS - SECTOR_SIZE_BITS);  sectorInPage = (int) (sectorNo) % ADDRESSES_PER_SECTOR;  updatedPage = vol.pageTable[pageNo];  virtualMapEntryAddress = logical2Physical(&vol,updatedPage) +				 sectorInPage * sizeof(LogicalAddress);  oldAddress = LE4(*(LEulong FAR0 *)	vol.flash.map(&vol.flash,virtualMapEntryAddress,sizeof(LogicalAddress)));  if (oldAddress == DELETED_ADDRESS && vol.replacementPageNo == pageNo) {    updatedPage = vol.replacementPageAddress;    virtualMapEntryAddress = logical2Physical(&vol,updatedPage) +				   sectorInPage * sizeof(LogicalAddress);    oldAddress = LE4(*(LEulong FAR0 *)	  vol.flash.map(&vol.flash,virtualMapEntryAddress,sizeof(LogicalAddress)));  }  if (newAddress == DELETED_ADDRESS && ((unsigned long)oldAddress == UNASSIGNED_ADDRESS))    return flOK;  toLE4(addressToWrite,(LogicalAddress) newAddress << SECTOR_SIZE_BITS);  if (cannotWriteOver(LE4(addressToWrite),oldAddress)) {    FLStatus status;    if (pageNo != vol.replacementPageNo ||	updatedPage == vol.replacementPageAddress) {      if (vol.replacementPageNo != UNASSIGNED_SECTOR)	checkStatus(closeReplacementPage(&vol));      checkStatus(allocateAndWriteSector(&vol,pageNo,NULL,TRUE));    }    status = flashWrite(&vol,			logical2Physical(&vol,vol.replacementPageAddress) +				      sectorInPage * sizeof(LogicalAddress),			&addressToWrite,			sizeof addressToWrite,			0);    if (status != flOK) {      closeReplacementPage(&vol);				/* we may get a write-error because a				   previous cache update did not complete. */      return status;    }    toLE4(addressToWrite,DELETED_ADDRESS);    updatedPage = vol.pageTable[pageNo];  }  checkStatus(flashWrite(&vol,			 logical2Physical(&vol,updatedPage) +				   sectorInPage * sizeof(LogicalAddress),			 &addressToWrite,			 sizeof addressToWrite,			 (unsigned long)oldAddress != UNASSIGNED_ADDRESS));

⌨️ 快捷键说明

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