userlibandfileserver/fileserver/sfat/fat_table.cpp
changeset 15 4122176ea935
parent 0 a41df078684a
equal deleted inserted replaced
0:a41df078684a 15:4122176ea935
    19 /**
    19 /**
    20  @file
    20  @file
    21  @internalTechnology
    21  @internalTechnology
    22 */
    22 */
    23 
    23 
       
    24 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    25 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    26 //!!
       
    27 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
       
    28 //!!
       
    29 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    30 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    24 
    31 
    25 
    32 
    26 #include "sl_std.h"
    33 #include "sl_std.h"
    27 #include "sl_fatcache.h"
    34 #include "sl_fatcache.h"
    28 #include "fat_table.h"
    35 #include "fat_table.h"
    40     @param aLocDrvCaps local drive attributes
    47     @param aLocDrvCaps local drive attributes
    41     @leave KErrNoMemory
    48     @leave KErrNoMemory
    42     @return Pointer to the Fat table
    49     @return Pointer to the Fat table
    43 */
    50 */
    44 CFatTable* CFatTable::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps)
    51 CFatTable* CFatTable::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps)
    45 	{
    52     {
    46     CFatTable* pFatTable=NULL;
    53     CFatTable* pFatTable=NULL;
    47 
    54 
    48     
    55     
    49     switch(aLocDrvCaps.iType)
    56     switch(aLocDrvCaps.iType)
    50         {
    57         {
    51         case EMediaRam:
    58         case EMediaRam:
    52 		    {//-- this is RAM media, try to create CRamFatTable instance.
    59             {//-- this is RAM media, try to create CRamFatTable instance.
    53             const TFatType fatType = aOwner.FatType();
    60             const TFatType fatType = aOwner.FatType();
    54             
    61             
    55             if(fatType != EFat16 )
    62             if(fatType != EFat16 )
    56                 {//-- CRamFatTable doesn't support FAT12; FAT16 only.
    63                 {//-- CRamFatTable doesn't support FAT12; FAT16 only.
    57                 __PRINT1(_L("CFatTable::NewL() CRamFatTable doesn't support this FAT type:%d"), fatType);
    64                 __PRINT1(_L("CFatTable::NewL() CRamFatTable doesn't support this FAT type:%d"), fatType);
    63             }
    70             }
    64         break;
    71         break;
    65 
    72 
    66         default:
    73         default:
    67             //-- other media
    74             //-- other media
    68 		    pFatTable = CAtaFatTable::NewL(aOwner);
    75             pFatTable = CAtaFatTable::NewL(aOwner);
    69         break;
    76         break;
    70         };
    77         };
    71 
    78 
    72 	return pFatTable;
    79     return pFatTable;
    73 	}
    80     }
    74 
    81 
    75 CFatTable::CFatTable(CFatMountCB& aOwner)
    82 CFatTable::CFatTable(CFatMountCB& aOwner)
    76 {
    83 {
    77     iOwner = &aOwner;
    84     iOwner = &aOwner;
    78     ASSERT(iOwner);
    85     ASSERT(iOwner);
    89 
    96 
    90 /**
    97 /**
    91     Initialise the object, get data from the owning CFatMountCB
    98     Initialise the object, get data from the owning CFatMountCB
    92 */
    99 */
    93 void CFatTable::InitializeL()
   100 void CFatTable::InitializeL()
    94 	{
   101     {
    95 	ASSERT(iOwner);
   102     ASSERT(iOwner);
    96 
   103 
    97     //-- get FAT type from the owner
   104     //-- get FAT type from the owner
    98     iFatType = iOwner->FatType();
   105     iFatType = iOwner->FatType();
    99     ASSERT(IsFat12() || IsFat16());
   106     ASSERT(IsFat12() || IsFat16());
   100 
   107 
   101     iFreeClusterHint = KFatFirstSearchCluster;
   108     iFreeClusterHint = KFatFirstSearchCluster;
   102 
   109 
   103     //-- cache the media attributes
   110     //-- cache the media attributes
   104 	TLocalDriveCapsV2 caps;
   111     TLocalDriveCapsV2 caps;
   105 	TPckg<TLocalDriveCapsV2> capsPckg(caps);
   112     TPckg<TLocalDriveCapsV2> capsPckg(caps);
   106     User::LeaveIfError(iOwner->LocalDrive()->Caps(capsPckg));
   113     User::LeaveIfError(iOwner->LocalDrive()->Caps(capsPckg));
   107 	iMediaAtt = caps.iMediaAtt;
   114     iMediaAtt = caps.iMediaAtt;
   108 	
   115     
   109     //-- obtain maximal number of entries in the table
   116     //-- obtain maximal number of entries in the table
   110     iMaxEntries = iOwner->UsableClusters()+KFatFirstSearchCluster; //-- FAT[0] & FAT[1] are not in use
   117     iMaxEntries = iOwner->UsableClusters()+KFatFirstSearchCluster; //-- FAT[0] & FAT[1] are not in use
   111 
   118 
   112     __PRINT3(_L("CFatTable::InitializeL(), drv:%d, iMediaAtt = %08X, max Entries:%d"), iOwner->DriveNumber(), iMediaAtt, iMaxEntries);
   119     __PRINT3(_L("CFatTable::InitializeL(), drv:%d, iMediaAtt = %08X, max Entries:%d"), iOwner->DriveNumber(), iMediaAtt, iMaxEntries);
   113 	}
   120     }
   114 
   121 
   115 //-----------------------------------------------------------------------------
   122 //-----------------------------------------------------------------------------
   116 
   123 
   117 /** 
   124 /** 
   118     Decrements the free cluster count.
   125     Decrements the free cluster count.
   134 
   141 
   135     @param  aCount a number of clusters 
   142     @param  aCount a number of clusters 
   136 */
   143 */
   137 void CFatTable::IncrementFreeClusterCount(TUint32 aCount)
   144 void CFatTable::IncrementFreeClusterCount(TUint32 aCount)
   138 {
   145 {
   139 	const TUint32 newVal = iFreeClusters+aCount;
   146     const TUint32 newVal = iFreeClusters+aCount;
   140     __ASSERT_DEBUG(newVal<=MaxEntries(), Fault(EFatCorrupt));
   147     __ASSERT_DEBUG(newVal<=MaxEntries(), Fault(EFatCorrupt));
   141     
   148     
   142     iFreeClusters = newVal;
   149     iFreeClusters = newVal;
   143 }
   150 }
   144 
   151 
   200     TTime   timeStart;
   207     TTime   timeStart;
   201     TTime   timeEnd;
   208     TTime   timeEnd;
   202     timeStart.UniversalTime(); //-- take start time
   209     timeStart.UniversalTime(); //-- take start time
   203 
   210 
   204     //-- walk through whole FAT table looking for free clusters
   211     //-- walk through whole FAT table looking for free clusters
   205 	for(TUint i=KFatFirstSearchCluster; i<MaxEntries(); ++i)
   212     for(TUint i=KFatFirstSearchCluster; i<MaxEntries(); ++i)
   206     {
   213     {
   207 	    if(ReadL(i) == KSpareCluster)
   214         if(ReadL(i) == KSpareCluster)
   208         {//-- found a free cluster
   215         {//-- found a free cluster
   209 		    ++freeClusters;
   216             ++freeClusters;
   210             
   217             
   211             if(!firstFreeCluster)
   218             if(!firstFreeCluster)
   212                 firstFreeCluster = i;
   219                 firstFreeCluster = i;
   213         }
   220         }
   214 	}
   221     }
   215 
   222 
   216     timeEnd.UniversalTime(); //-- take end time
   223     timeEnd.UniversalTime(); //-- take end time
   217     const TInt msScanTime = (TInt)( (timeEnd.MicroSecondsFrom(timeStart)).Int64() / K1mSec);
   224     const TInt msScanTime = (TInt)( (timeEnd.MicroSecondsFrom(timeStart)).Int64() / K1mSec);
   218     __PRINT1(_L("#- CFatTable::CountFreeClustersL() finished. Taken:%d ms"), msScanTime);
   225     __PRINT1(_L("#- CFatTable::CountFreeClustersL() finished. Taken:%d ms"), msScanTime);
   219     (void)msScanTime;
   226     (void)msScanTime;
   237 @param aMaxCount Maximum cluster required
   244 @param aMaxCount Maximum cluster required
   238 @leave System wide error values
   245 @leave System wide error values
   239 @return Number of contiguous clusters from aStartCluster.
   246 @return Number of contiguous clusters from aStartCluster.
   240 */
   247 */
   241 TInt CFatTable::CountContiguousClustersL(TUint32 aStartCluster,TInt& anEndCluster,TUint32 aMaxCount) const
   248 TInt CFatTable::CountContiguousClustersL(TUint32 aStartCluster,TInt& anEndCluster,TUint32 aMaxCount) const
   242 	{
   249     {
   243 	__PRINT2(_L("CFatTable::CountContiguousClustersL() start:%d, max:%d"),aStartCluster, aMaxCount);
   250     __PRINT2(_L("CFatTable::CountContiguousClustersL() start:%d, max:%d"),aStartCluster, aMaxCount);
   244 	TUint32 clusterListLen=1;
   251     TUint32 clusterListLen=1;
   245 	TInt endCluster=aStartCluster;
   252     TInt endCluster=aStartCluster;
   246 	TInt64 endClusterPos=DataPositionInBytes(endCluster);
   253     TInt64 endClusterPos=DataPositionInBytes(endCluster);
   247 	while (clusterListLen<aMaxCount)
   254     while (clusterListLen<aMaxCount)
   248 		{
   255         {
   249 		TInt oldCluster=endCluster;
   256         TInt oldCluster=endCluster;
   250 		TInt64 oldClusterPos=endClusterPos;
   257         TInt64 oldClusterPos=endClusterPos;
   251 		if (GetNextClusterL(endCluster)==EFalse || (endClusterPos=DataPositionInBytes(endCluster))!=(oldClusterPos+(1<<iOwner->ClusterSizeLog2())))
   258         if (GetNextClusterL(endCluster)==EFalse || (endClusterPos=DataPositionInBytes(endCluster))!=(oldClusterPos+(1<<iOwner->ClusterSizeLog2())))
   252 			{
   259             {
   253 			endCluster=oldCluster;
   260             endCluster=oldCluster;
   254 			break;
   261             break;
   255 			}
   262             }
   256 		clusterListLen++;
   263         clusterListLen++;
   257 		}
   264         }
   258 	anEndCluster=endCluster;
   265     anEndCluster=endCluster;
   259 	return(clusterListLen);
   266     return(clusterListLen);
   260 	}	
   267     }   
   261 
   268 
   262 //-----------------------------------------------------------------------------
   269 //-----------------------------------------------------------------------------
   263 
   270 
   264 /**
   271 /**
   265     Extend a file or directory cluster chain, leaves if there are no free clusters (the disk is full).
   272     Extend a file or directory cluster chain, leaves if there are no free clusters (the disk is full).
   268     @param aCluster FAT entry index to start with.
   275     @param aCluster FAT entry index to start with.
   269 
   276 
   270     @leave KErrDiskFull + system wide error codes
   277     @leave KErrDiskFull + system wide error codes
   271 */
   278 */
   272 void CFatTable::ExtendClusterListL(TUint32 aNumber,TInt& aCluster)
   279 void CFatTable::ExtendClusterListL(TUint32 aNumber,TInt& aCluster)
   273 	{
   280     {
   274 	__PRINT2(_L("CFatTable::ExtendClusterListL() num:%d, clust:%d"), aNumber, aCluster);
   281     __PRINT2(_L("CFatTable::ExtendClusterListL() num:%d, clust:%d"), aNumber, aCluster);
   275 	__ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
   282     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
   276 	
   283     
   277 	while(aNumber && GetNextClusterL(aCluster))
   284     while(aNumber && GetNextClusterL(aCluster))
   278 		aNumber--;
   285         aNumber--;
   279 
   286 
   280     if(!aNumber)
   287     if(!aNumber)
   281         return;
   288         return;
   282 
   289 
   283 	if (iFreeClusters<aNumber)
   290     if (iFreeClusters<aNumber)
   284 		{
   291         {
   285 		__PRINT(_L("CFatTable::ExtendClusterListL - leaving KErrDirFull"));
   292         __PRINT(_L("CFatTable::ExtendClusterListL - leaving KErrDirFull"));
   286 		User::Leave(KErrDiskFull);
   293         User::Leave(KErrDiskFull);
   287 		}
   294         }
   288 
   295 
   289 
   296 
   290     TUint32 freeCluster = 0;
   297     TUint32 freeCluster = 0;
   291     
   298     
   292     //-- note: this can be impoved by trying to fing as long chain of free clusters as possible in FindClosestFreeClusterL()
   299     //-- note: this can be impoved by trying to fing as long chain of free clusters as possible in FindClosestFreeClusterL()
   293     for(TUint i=0; i<aNumber; ++i)
   300     for(TUint i=0; i<aNumber; ++i)
   294 		{
   301         {
   295         freeCluster = FindClosestFreeClusterL(aCluster);
   302         freeCluster = FindClosestFreeClusterL(aCluster);
   296 		WriteFatEntryEofL(freeCluster); //	Must write EOF for FindClosestFreeCluster to work again
   303         WriteFatEntryEofL(freeCluster); //  Must write EOF for FindClosestFreeCluster to work again
   297 		WriteL(aCluster,freeCluster);
   304         WriteL(aCluster,freeCluster);
   298 		aCluster=freeCluster;
   305         aCluster=freeCluster;
   299 		}
   306         }
   300     
   307     
   301     //-- decrement number of available clusters
   308     //-- decrement number of available clusters
   302     DecrementFreeClusterCount(aNumber);
   309     DecrementFreeClusterCount(aNumber);
   303 
   310 
   304     //-- update free cluster hint, it isn't required to be a precise value, just a hint where to start the from from
   311     //-- update free cluster hint, it isn't required to be a precise value, just a hint where to start the from from
   305     SetFreeClusterHint(aCluster); 
   312     SetFreeClusterHint(aCluster); 
   306     
   313     
   307 	}
   314     }
   308 
   315 
   309 //-----------------------------------------------------------------------------
   316 //-----------------------------------------------------------------------------
   310 
   317 
   311 /**
   318 /**
   312 Allocate and mark as EOF a single cluster as close as possible to aNearestCluster
   319 Allocate and mark as EOF a single cluster as close as possible to aNearestCluster
   314 @param aNearestCluster Cluster the new cluster should be nearest to
   321 @param aNearestCluster Cluster the new cluster should be nearest to
   315 @leave System wide error codes
   322 @leave System wide error codes
   316 @return The cluster number allocated
   323 @return The cluster number allocated
   317 */
   324 */
   318 TUint32 CFatTable::AllocateSingleClusterL(TUint32 aNearestCluster)
   325 TUint32 CFatTable::AllocateSingleClusterL(TUint32 aNearestCluster)
   319 	{
   326     {
   320 	__PRINT1(_L("CFatTable::AllocateSingleCluster() nearest:%d"), aNearestCluster);
   327     __PRINT1(_L("CFatTable::AllocateSingleCluster() nearest:%d"), aNearestCluster);
   321 	if (iFreeClusters==0)
   328     if (iFreeClusters==0)
   322 		User::Leave(KErrDiskFull);
   329         User::Leave(KErrDiskFull);
   323 	const TInt freeCluster=FindClosestFreeClusterL(aNearestCluster);
   330     const TInt freeCluster=FindClosestFreeClusterL(aNearestCluster);
   324 	WriteFatEntryEofL(freeCluster);
   331     WriteFatEntryEofL(freeCluster);
   325 	DecrementFreeClusterCount(1);
   332     DecrementFreeClusterCount(1);
   326 
   333 
   327     //-- update free cluster hint, it isn't required to be a precise value, just a hint where to start the from from.
   334     //-- update free cluster hint, it isn't required to be a precise value, just a hint where to start the from from.
   328     SetFreeClusterHint(freeCluster); 
   335     SetFreeClusterHint(freeCluster); 
   329 
   336 
   330 	return(freeCluster);
   337     return(freeCluster);
   331 	}	
   338     }   
   332 
   339 
   333 //-----------------------------------------------------------------------------
   340 //-----------------------------------------------------------------------------
   334 
   341 
   335 /**
   342 /**
   336 Allocate and link a cluster chain, leaves if there are not enough free clusters.
   343 Allocate and link a cluster chain, leaves if there are not enough free clusters.
   340 @param aNearestCluster Cluster the new chain should be nearest to
   347 @param aNearestCluster Cluster the new chain should be nearest to
   341 @leave System wide error codes
   348 @leave System wide error codes
   342 @return The first cluster number allocated
   349 @return The first cluster number allocated
   343 */
   350 */
   344 TUint32 CFatTable::AllocateClusterListL(TUint32 aNumber, TUint32 aNearestCluster)
   351 TUint32 CFatTable::AllocateClusterListL(TUint32 aNumber, TUint32 aNearestCluster)
   345 	{
   352     {
   346     __PRINT2(_L("#>> CFatTable::AllocateClusterList() N:%d,NearestCL:%d"),aNumber,aNearestCluster);
   353     __PRINT2(_L("#>> CFatTable::AllocateClusterList() N:%d,NearestCL:%d"),aNumber,aNearestCluster);
   347 	__ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
   354     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
   348 
   355 
   349 	if (iFreeClusters<aNumber)
   356     if (iFreeClusters<aNumber)
   350 		{
   357         {
   351 		__PRINT(_L("CFatTable::AllocateClusterListL - leaving KErrDirFull"));
   358         __PRINT(_L("CFatTable::AllocateClusterListL - leaving KErrDirFull"));
   352 		User::Leave(KErrDiskFull);
   359         User::Leave(KErrDiskFull);
   353 		}
   360         }
   354 
   361 
   355     TInt firstCluster = aNearestCluster = AllocateSingleClusterL(aNearestCluster);
   362     TInt firstCluster = aNearestCluster = AllocateSingleClusterL(aNearestCluster);
   356 	if (aNumber>1)
   363     if (aNumber>1)
   357 		ExtendClusterListL(aNumber-1, (TInt&)aNearestCluster);
   364         ExtendClusterListL(aNumber-1, (TInt&)aNearestCluster);
   358 
   365 
   359 	return(firstCluster);
   366     return(firstCluster);
   360 	}	
   367     }   
   361 
   368 
   362 //-----------------------------------------------------------------------------
   369 //-----------------------------------------------------------------------------
   363 
   370 
   364 /**
   371 /**
   365     Notify the media drive about media areas that shall be treated as "deleted" if this feature is supported.
   372     Notify the media drive about media areas that shall be treated as "deleted" if this feature is supported.
   376     
   383     
   377     FlushL(); //-- Commit the FAT changes to disk first to be safe
   384     FlushL(); //-- Commit the FAT changes to disk first to be safe
   378 
   385 
   379     const TUint bytesPerCluster = 1 << iOwner->ClusterSizeLog2();
   386     const TUint bytesPerCluster = 1 << iOwner->ClusterSizeLog2();
   380 
   387 
   381     TInt64  byteAddress = 0;	
   388     TInt64  byteAddress = 0;    
   382 	TUint   deleteLen = 0;	// zero indicates no clusters accumulated yet
   389     TUint   deleteLen = 0;  // zero indicates no clusters accumulated yet
   383 
   390 
   384 	for (TUint i=0; i<clusterCount; ++i)
   391     for (TUint i=0; i<clusterCount; ++i)
   385 	{
   392     {
   386         const TUint currCluster = aFreedClusters[i];
   393         const TUint currCluster = aFreedClusters[i];
   387         
   394         
   388         if (deleteLen == 0)
   395         if (deleteLen == 0)
   389 		    byteAddress = DataPositionInBytes(currCluster); //-- start of the media range
   396             byteAddress = DataPositionInBytes(currCluster); //-- start of the media range
   390         
   397         
   391         deleteLen += bytesPerCluster;
   398         deleteLen += bytesPerCluster;
   392 
   399 
   393         //-- if this is the last entry in the array or the net cluster number is not consecutive, notify the driver
   400         //-- if this is the last entry in the array or the net cluster number is not consecutive, notify the driver
   394 		if ((i+1) == clusterCount || aFreedClusters[i+1] != (currCluster+1))
   401         if ((i+1) == clusterCount || aFreedClusters[i+1] != (currCluster+1))
   395         {
   402         {
   396             //__PRINT3(_L("DeleteNotify(%08X:%08X, %u), first cluster %u last cluster #%u"), I64HIGH(byteAddress), I64LOW(byteAddress), deleteLen);
   403             //__PRINT3(_L("DeleteNotify(%08X:%08X, %u), first cluster %u last cluster #%u"), I64HIGH(byteAddress), I64LOW(byteAddress), deleteLen);
   397 			//__PRINT2(_L("   first cluster %u last cluster #%u"), I64LOW((byteAddress - iOwner->ClusterBasePosition()) >> iOwner->ClusterSizeLog2()) + 2, cluster);
   404             //__PRINT2(_L("   first cluster %u last cluster #%u"), I64LOW((byteAddress - iOwner->ClusterBasePosition()) >> iOwner->ClusterSizeLog2()) + 2, cluster);
   398             const TInt r = iOwner->LocalDrive()->DeleteNotify(byteAddress, deleteLen);
   405             const TInt r = iOwner->LocalDrive()->DeleteNotify(byteAddress, deleteLen);
   399 			if(r != KErrNone)
   406             if(r != KErrNone)
   400                 {//-- if DeleteNotify() failed, it means that something terribly wrong happened to the NAND media; 
   407                 {//-- if DeleteNotify() failed, it means that something terribly wrong happened to the NAND media; 
   401                  //-- in normal circumstances it can not happen. One of the reasons: totally worn out media.
   408                  //-- in normal circumstances it can not happen. One of the reasons: totally worn out media.
   402                 const TBool platSecEnabled = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement);
   409                 const TBool platSecEnabled = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement);
   403                 __PRINT3(_L("CFatTable::DoFreedClustersNotify() DeleteNotify failure! drv:%d err:%d, PlatSec:%d"),iOwner->DriveNumber(), r, platSecEnabled);
   410                 __PRINT3(_L("CFatTable::DoFreedClustersNotify() DeleteNotify failure! drv:%d err:%d, PlatSec:%d"),iOwner->DriveNumber(), r, platSecEnabled);
   404 
   411 
   412                     {
   419                     {
   413                     //-- if PlatSec is disabled, it's OK to ignore the NAND fault in release mode.
   420                     //-- if PlatSec is disabled, it's OK to ignore the NAND fault in release mode.
   414                     __ASSERT_DEBUG(0, Fault(EFatBadLocalDrive));
   421                     __ASSERT_DEBUG(0, Fault(EFatBadLocalDrive));
   415                     }        
   422                     }        
   416                 }
   423                 }
   417 			
   424             
   418             
   425             
   419             deleteLen = 0;
   426             deleteLen = 0;
   420         }
   427         }
   421 
   428 
   422     }
   429     }
   431 
   438 
   432 @param aCluster Start cluster of cluster chain to free
   439 @param aCluster Start cluster of cluster chain to free
   433 @leave System wide error codes
   440 @leave System wide error codes
   434 */
   441 */
   435 void CFatTable::FreeClusterListL(TUint32 aCluster)
   442 void CFatTable::FreeClusterListL(TUint32 aCluster)
   436 	{
   443     {
   437 	__PRINT1(_L("CFatTable::FreeClusterListL startCluster=%d"),aCluster);
   444     __PRINT1(_L("CFatTable::FreeClusterListL startCluster=%d"),aCluster);
   438 	if (aCluster == KSpareCluster)
   445     if (aCluster == KSpareCluster)
   439 		return; 
   446         return; 
   440 
   447 
   441 	//-- here we can store array of freed cluster numbers in order to 
   448     //-- here we can store array of freed cluster numbers in order to 
   442     //-- notify media drive about the media addresses marked as "invalid"
   449     //-- notify media drive about the media addresses marked as "invalid"
   443     RClusterArray deletedClusters;      
   450     RClusterArray deletedClusters;      
   444 	CleanupClosePushL(deletedClusters);
   451     CleanupClosePushL(deletedClusters);
   445 
   452 
   446     //-- if ETrue, we need to notify media driver about invalidated media addressses
   453     //-- if ETrue, we need to notify media driver about invalidated media addressses
   447     const TBool bFreeClustersNotify = iMediaAtt & KMediaAttDeleteNotify;
   454     const TBool bFreeClustersNotify = iMediaAtt & KMediaAttDeleteNotify;
   448 
   455 
   449     //-- this is a maximal number of FAT entries in the deletedClusters array.
   456     //-- this is a maximal number of FAT entries in the deletedClusters array.
   458 
   465 
   459     TUint32 currCluster = aCluster;
   466     TUint32 currCluster = aCluster;
   460     TInt    nextCluster = aCluster;
   467     TInt    nextCluster = aCluster;
   461 
   468 
   462     for(;;)
   469     for(;;)
   463 		{
   470         {
   464         const TBool bEOF = !GetNextClusterL(nextCluster);    
   471         const TBool bEOF = !GetNextClusterL(nextCluster);    
   465         WriteL(currCluster, KSpareCluster);
   472         WriteL(currCluster, KSpareCluster);
   466 
   473 
   467         lastKnownFreeCluster = Min(currCluster, lastKnownFreeCluster);
   474         lastKnownFreeCluster = Min(currCluster, lastKnownFreeCluster);
   468 
   475 
   469 		// Keep a record of the deleted clusters so that we can subsequently notify the media driver. This is only safe 
   476         // Keep a record of the deleted clusters so that we can subsequently notify the media driver. This is only safe 
   470 		// to do once the FAT changes have been written to disk.
   477         // to do once the FAT changes have been written to disk.
   471         if(bFreeClustersNotify)
   478         if(bFreeClustersNotify)
   472             deletedClusters.Append(currCluster);
   479             deletedClusters.Append(currCluster);
   473 
   480 
   474         ++cntFreedClusters;
   481         ++cntFreedClusters;
   475         currCluster = nextCluster;
   482         currCluster = nextCluster;
   476 
   483 
   477 		if (bEOF || aCluster == KSpareCluster)
   484         if (bEOF || aCluster == KSpareCluster)
   478 			break;
   485             break;
   479 
   486 
   480         if(bFreeClustersNotify && cntFreedClusters && (cntFreedClusters & (KSubListLen-1))==0)
   487         if(bFreeClustersNotify && cntFreedClusters && (cntFreedClusters & (KSubListLen-1))==0)
   481         {//-- reached a limit of the entries in the array. Flush FAT cache, notify the driver and empty the array.
   488         {//-- reached a limit of the entries in the array. Flush FAT cache, notify the driver and empty the array.
   482             IncrementFreeClusterCount(cntFreedClusters);
   489             IncrementFreeClusterCount(cntFreedClusters);
   483             cntFreedClusters = 0;
   490             cntFreedClusters = 0;
   493     SetFreeClusterHint(lastKnownFreeCluster);
   500     SetFreeClusterHint(lastKnownFreeCluster);
   494     
   501     
   495     if(bFreeClustersNotify)
   502     if(bFreeClustersNotify)
   496     DoFreedClustersNotify(deletedClusters);
   503     DoFreedClustersNotify(deletedClusters);
   497 
   504 
   498 	CleanupStack::PopAndDestroy(&deletedClusters);
   505     CleanupStack::PopAndDestroy(&deletedClusters);
   499 	}
   506     }
   500 
   507 
   501 //-----------------------------------------------------------------------------
   508 //-----------------------------------------------------------------------------
   502 
   509 
   503 /**
   510 /**
   504 Find a free cluster nearest to aCluster, Always checks to the right of aCluster first 
   511 Find a free cluster nearest to aCluster, Always checks to the right of aCluster first 
   507 @param aCluster Cluster to find nearest free cluster to.
   514 @param aCluster Cluster to find nearest free cluster to.
   508 @leave KErrDiskFull + system wide error codes
   515 @leave KErrDiskFull + system wide error codes
   509 @return cluster number found
   516 @return cluster number found
   510 */
   517 */
   511 TUint32 CFatTable::FindClosestFreeClusterL(TUint32 aCluster)
   518 TUint32 CFatTable::FindClosestFreeClusterL(TUint32 aCluster)
   512 	{
   519     {
   513     __PRINT2(_L("CFatTable::FindClosestFreeClusterL() drv:%d cl:%d"),iOwner->DriveNumber(),aCluster);
   520     __PRINT2(_L("CFatTable::FindClosestFreeClusterL() drv:%d cl:%d"),iOwner->DriveNumber(),aCluster);
   514 
   521 
   515     if(!ClusterNumberValid(aCluster))
   522     if(!ClusterNumberValid(aCluster))
   516         {
   523         {
   517         ASSERT(0);
   524         ASSERT(0);
   518         User::Leave(KErrCorrupt);
   525         User::Leave(KErrCorrupt);
   519         }
   526         }
   520 
   527 
   521 
   528 
   522     if(iFreeClusters==0)
   529     if(iFreeClusters==0)
   523 	    {//-- there is no at least 1 free cluster available
   530         {//-- there is no at least 1 free cluster available
   524     	__PRINT(_L("CFatTable::FindClosestFreeClusterL() leaving KErrDiskFull #1"));
   531         __PRINT(_L("CFatTable::FindClosestFreeClusterL() leaving KErrDiskFull #1"));
   525 		User::Leave(KErrDiskFull);
   532         User::Leave(KErrDiskFull);
   526         }
   533         }
   527 	
   534     
   528     //-- 1. look if the given index contains a free entry 
   535     //-- 1. look if the given index contains a free entry 
   529     if(ReadL(aCluster) != KSpareCluster)
   536     if(ReadL(aCluster) != KSpareCluster)
   530         {//-- no, it doesn't...
   537         {//-- no, it doesn't...
   531         
   538         
   532         //-- 2. look in both directions starting from the aCluster, looking in the right direction first
   539         //-- 2. look in both directions starting from the aCluster, looking in the right direction first
   558                 else        
   565                 else        
   559                     canGoLeft = EFalse;
   566                     canGoLeft = EFalse;
   560                 }
   567                 }
   561 
   568 
   562         if(!canGoRight && !canGoLeft)
   569         if(!canGoRight && !canGoLeft)
   563 	        {
   570             {
   564     	    __PRINT(_L("CFatTable::FindClosestFreeClusterL() leaving KErrDiskFull #2"));
   571             __PRINT(_L("CFatTable::FindClosestFreeClusterL() leaving KErrDiskFull #2"));
   565             User::Leave(KErrDiskFull);
   572             User::Leave(KErrDiskFull);
   566             }
   573             }
   567 
   574 
   568         if (canGoRight && ReadL(rightIdx) == KSpareCluster)
   575         if (canGoRight && ReadL(rightIdx) == KSpareCluster)
   569 			{
   576             {
   570 			aCluster = rightIdx;
   577             aCluster = rightIdx;
   571 			break;
   578             break;
   572 			}
   579             }
   573 
   580 
   574 		if (canGoLeft && ReadL(leftIdx) == KSpareCluster)
   581         if (canGoLeft && ReadL(leftIdx) == KSpareCluster)
   575 			{
   582             {
   576 			aCluster = leftIdx;
   583             aCluster = leftIdx;
   577 			break;
   584             break;
   578 			}
   585             }
   579             }//for(..)
   586             }//for(..)
   580 
   587 
   581         }//if(ReadL(aCluster) != KSpareCluster)
   588         }//if(ReadL(aCluster) != KSpareCluster)
   582 
   589 
   583 
   590 
   586     //-- the last known free cluster in the caller of this internal method.
   593     //-- the last known free cluster in the caller of this internal method.
   587 
   594 
   588 //    __PRINT1(_L("CFatTable::FindClosestFreeClusterL found:%d"),aCluster);
   595 //    __PRINT1(_L("CFatTable::FindClosestFreeClusterL found:%d"),aCluster);
   589 
   596 
   590     return aCluster;
   597     return aCluster;
   591 	}
   598     }
   592 
   599 
   593 //-----------------------------------------------------------------------------
   600 //-----------------------------------------------------------------------------
   594 
   601 
   595 /**
   602 /**
   596     Converts a cluster number to byte offset in the FAT
   603     Converts a cluster number to byte offset in the FAT
   597 
   604 
   598 @param aFatIndex Cluster number
   605 @param aFatIndex Cluster number
   599     @return Number of bytes from the beginning of the FAT
   606     @return Number of bytes from the beginning of the FAT
   600 */
   607 */
   601 TUint32 CFatTable::PosInBytes(TUint32 aFatIndex) const
   608 TUint32 CFatTable::PosInBytes(TUint32 aFatIndex) const
   602 	{
   609     {
   603     switch(FatType())
   610     switch(FatType())
   604         {
   611         {
   605         case EFat12:
   612         case EFat12:
   606             return (((aFatIndex>>1)<<1) + (aFatIndex>>1)); //-- 1.5 bytes per FAT entry
   613             return (((aFatIndex>>1)<<1) + (aFatIndex>>1)); //-- 1.5 bytes per FAT entry
   607 
   614 
   611         default:
   618         default:
   612             ASSERT(0);
   619             ASSERT(0);
   613             return 0;//-- get rid of warning
   620             return 0;//-- get rid of warning
   614         };
   621         };
   615 
   622 
   616 	}
   623     }
   617 
   624 
   618 //-----------------------------------------------------------------------------
   625 //-----------------------------------------------------------------------------
   619 
   626 
   620 /**
   627 /**
   621     Checks if we have at least aClustersRequired clusters free in the FAT.
   628     Checks if we have at least aClustersRequired clusters free in the FAT.
   649 /**
   656 /**
   650 Constructor
   657 Constructor
   651 */
   658 */
   652 CAtaFatTable::CAtaFatTable(CFatMountCB& aOwner)
   659 CAtaFatTable::CAtaFatTable(CFatMountCB& aOwner)
   653              :CFatTable(aOwner)
   660              :CFatTable(aOwner)
   654 	{
   661     {
   655 	}
   662     }
   656 
   663 
   657 
   664 
   658 /** factory method */
   665 /** factory method */
   659 CAtaFatTable* CAtaFatTable::NewL(CFatMountCB& aOwner)
   666 CAtaFatTable* CAtaFatTable::NewL(CFatMountCB& aOwner)
   660 {
   667 {
   678 void CAtaFatTable::CreateCacheL()
   685 void CAtaFatTable::CreateCacheL()
   679 {
   686 {
   680     ASSERT(iOwner);
   687     ASSERT(iOwner);
   681     const TUint32 fatSize=iOwner->FatSizeInBytes();
   688     const TUint32 fatSize=iOwner->FatSizeInBytes();
   682     __PRINT3(_L("CAtaFatTable::CreateCacheL drv:%d, FAT:%d, FAT Size:%d"), iOwner->DriveNumber(), FatType(), fatSize);
   689     __PRINT3(_L("CAtaFatTable::CreateCacheL drv:%d, FAT:%d, FAT Size:%d"), iOwner->DriveNumber(), FatType(), fatSize);
   683 	
   690     
   684 
   691 
   685     //-- according to FAT specs:
   692     //-- according to FAT specs:
   686     //-- FAT12 max size is 4084 entries or 6126 bytes                                               => create fixed cache for whole FAT
   693     //-- FAT12 max size is 4084 entries or 6126 bytes                                               => create fixed cache for whole FAT
   687     //-- FAT16 min size is 4085 entries or 8170 bytes, max size is 65525 entries or 131048 bytes    => create fixed cache for whole FAT
   694     //-- FAT16 min size is 4085 entries or 8170 bytes, max size is 65525 entries or 131048 bytes    => create fixed cache for whole FAT
   688 
   695 
   716         }
   723         }
   717         break;
   724         break;
   718 
   725 
   719         default:
   726         default:
   720         ASSERT(0);
   727         ASSERT(0);
   721 		User::Leave(KErrCorrupt);
   728         User::Leave(KErrCorrupt);
   722         break;
   729         break;
   723     };
   730     };
   724 
   731 
   725     ASSERT(iCache);
   732     ASSERT(iCache);
   726 }
   733 }
   731 /**
   738 /**
   732     Flush the FAT cache on disk
   739     Flush the FAT cache on disk
   733 @leave System wide error codes
   740 @leave System wide error codes
   734 */
   741 */
   735 void CAtaFatTable::FlushL()
   742 void CAtaFatTable::FlushL()
   736 	{
   743     {
   737     //-- the data can't be written if the mount is inconsistent
   744     //-- the data can't be written if the mount is inconsistent
   738     iOwner->CheckStateConsistentL();
   745     iOwner->CheckStateConsistentL();
   739 
   746 
   740 	if (iCache)
   747     if (iCache)
   741 		iCache->FlushL();
   748         iCache->FlushL();
   742 	}
   749     }
   743 
   750 
   744 /**
   751 /**
   745 Clear any cached data
   752 Clear any cached data
   746     @param aDiscardDirtyData if ETrue, non-flushed data in the cache will be discarded.
   753     @param aDiscardDirtyData if ETrue, non-flushed data in the cache will be discarded.
   747 */
   754 */
   748 void CAtaFatTable::Dismount(TBool aDiscardDirtyData)
   755 void CAtaFatTable::Dismount(TBool aDiscardDirtyData)
   749 	{
   756     {
   750 	if (iCache)
   757     if (iCache)
   751 		{
   758         {
   752         //-- cache's Close() can check if the cache is clean. 
   759         //-- cache's Close() can check if the cache is clean. 
   753         //-- ignore dirty data in cache if the mount is not in consistent state (it's impossible to flush cache data)
   760         //-- ignore dirty data in cache if the mount is not in consistent state (it's impossible to flush cache data)
   754         //-- or if we are asked to do so.
   761         //-- or if we are asked to do so.
   755         const TBool bIgnoreDirtyData = aDiscardDirtyData || !iOwner->ConsistentState();
   762         const TBool bIgnoreDirtyData = aDiscardDirtyData || !iOwner->ConsistentState();
   756         iCache->Close(bIgnoreDirtyData);
   763         iCache->Close(bIgnoreDirtyData);
   757 
   764 
   758 		delete iCache;
   765         delete iCache;
   759 		iCache=NULL;
   766         iCache=NULL;
   760 		}
   767         }
   761 
   768 
   762 	}
   769     }
   763 
   770 
   764 //---------------------------------------------------------------------------------------------------------------------------------------
   771 //---------------------------------------------------------------------------------------------------------------------------------------
   765 
   772 
   766 /**
   773 /**
   767     Invalidate whole FAT cache.
   774     Invalidate whole FAT cache.
   788 
   795 
   789     @param aPos absolute media position where the region being invalidated starts.
   796     @param aPos absolute media position where the region being invalidated starts.
   790     @param aLength length in bytes of region to invalidate / refresh
   797     @param aLength length in bytes of region to invalidate / refresh
   791 */
   798 */
   792 void CAtaFatTable::InvalidateCacheL(TInt64 aPos, TUint32 aLength)
   799 void CAtaFatTable::InvalidateCacheL(TInt64 aPos, TUint32 aLength)
   793 	{
   800     {
   794     __PRINT3(_L("CAtaFatTable::InvalidateCacheL() drv:%d, pos:%LU, len:%u,"), iOwner->DriveNumber(), aPos, aLength);
   801     __PRINT3(_L("CAtaFatTable::InvalidateCacheL() drv:%d, pos:%LU, len:%u,"), iOwner->DriveNumber(), aPos, aLength);
   795 
   802 
   796     if(I64HIGH(aPos) || !aLength || I64HIGH(aPos+aLength))
   803     if(I64HIGH(aPos) || !aLength || I64HIGH(aPos+aLength))
   797         return; //-- FAT tables can't span over 4G 
   804         return; //-- FAT tables can't span over 4G 
   798 
   805 
   862         startFatEntry += KFatFirstSearchCluster;
   869         startFatEntry += KFatFirstSearchCluster;
   863         numEntries -= KFatFirstSearchCluster;
   870         numEntries -= KFatFirstSearchCluster;
   864     }
   871     }
   865 
   872 
   866     User::LeaveIfError(iCache->InvalidateRegion(startFatEntry, numEntries));
   873     User::LeaveIfError(iCache->InvalidateRegion(startFatEntry, numEntries));
   867 	}
   874     }
   868 
   875 
   869 
   876 
   870 //-----------------------------------------------------------------------------
   877 //-----------------------------------------------------------------------------
   871 /**
   878 /**
   872     Initialize the object, create FAT cache if required
   879     Initialize the object, create FAT cache if required
   873 @leave KErrNoMemory
   880 @leave KErrNoMemory
   874 */
   881 */
   875 void CAtaFatTable::InitializeL()
   882 void CAtaFatTable::InitializeL()
   876 	{
   883     {
   877     __PRINT1(_L("CAtaFatTable::InitializeL() drv:%d"), iOwner->DriveNumber());
   884     __PRINT1(_L("CAtaFatTable::InitializeL() drv:%d"), iOwner->DriveNumber());
   878     CFatTable::InitializeL();
   885     CFatTable::InitializeL();
   879 
   886 
   880     //-- create the FAT cache.
   887     //-- create the FAT cache.
   881     ASSERT(!iCache);
   888     ASSERT(!iCache);
   882     CreateCacheL();
   889     CreateCacheL();
   883 	}
   890     }
   884 
   891 
   885 
   892 
   886 //-----------------------------------------------------------------------------
   893 //-----------------------------------------------------------------------------
   887 /**
   894 /**
   888     Remount the FAT table. This method call means that the media parameters wasn't changed, 
   895     Remount the FAT table. This method call means that the media parameters wasn't changed, 
   912 
   919 
   913     @param aFatIndex FAT entry number to read
   920     @param aFatIndex FAT entry number to read
   914     @return FAT entry value
   921     @return FAT entry value
   915 */
   922 */
   916 TUint32 CAtaFatTable::ReadL(TUint32 aFatIndex) const
   923 TUint32 CAtaFatTable::ReadL(TUint32 aFatIndex) const
   917 	{
   924     {
   918     if(!ClusterNumberValid(aFatIndex))
   925     if(!ClusterNumberValid(aFatIndex))
   919         {
   926         {
   920         //ASSERT(0); //-- for some silly reason some callers pass 0 here and expect it to leave
   927         //ASSERT(0); //-- for some silly reason some callers pass 0 here and expect it to leave
   921         User::Leave(KErrCorrupt);
   928         User::Leave(KErrCorrupt);
   922         }
   929         }
   934     @param aFatIndex    aFatIndex FAT entry number to write
   941     @param aFatIndex    aFatIndex FAT entry number to write
   935     @param aValue       FAT entry to write
   942     @param aValue       FAT entry to write
   936 @leave
   943 @leave
   937 */
   944 */
   938 void CAtaFatTable::WriteL(TUint32 aFatIndex, TUint32 aValue)
   945 void CAtaFatTable::WriteL(TUint32 aFatIndex, TUint32 aValue)
   939 	{
   946     {
   940     const TUint32 KFat16EntryMask = 0x0FFFF;
   947     const TUint32 KFat16EntryMask = 0x0FFFF;
   941     
   948     
   942     __PRINT2(_L("CAtaFatTable::WriteL() entry:%d, val:0x%x"), aFatIndex, aValue);
   949     __PRINT2(_L("CAtaFatTable::WriteL() entry:%d, val:0x%x"), aFatIndex, aValue);
   943     
   950     
   944     if(!ClusterNumberValid(aFatIndex))
   951     if(!ClusterNumberValid(aFatIndex))
   951         {
   958         {
   952         ASSERT(0);
   959         ASSERT(0);
   953         User::Leave(KErrCorrupt);
   960         User::Leave(KErrCorrupt);
   954         }
   961         }
   955     iCache->WriteEntryL(aFatIndex, aValue);
   962     iCache->WriteEntryL(aFatIndex, aValue);
   956 	}
   963     }
   957 
   964 
   958 
   965 
   959 /**
   966 /**
   960 Get the next cluster in the chain from the FAT
   967 Get the next cluster in the chain from the FAT
   961 
   968 
   963 @leave
   970 @leave
   964 @return False if end of cluster chain
   971 @return False if end of cluster chain
   965 */
   972 */
   966 TBool CFatTable::GetNextClusterL(TInt& aCluster) const
   973 TBool CFatTable::GetNextClusterL(TInt& aCluster) const
   967     {
   974     {
   968 	__PRINT1(_L("CAtaFatTable::GetNextClusterL(%d)"), aCluster);
   975     __PRINT1(_L("CAtaFatTable::GetNextClusterL(%d)"), aCluster);
   969     
   976     
   970     const TInt nextCluster = ReadL(aCluster);
   977     const TInt nextCluster = ReadL(aCluster);
   971     TBool ret = EFalse; 
   978     TBool ret = EFalse; 
   972 
   979 
   973     switch(FatType())
   980     switch(FatType())
   982 
   989 
   983         default:
   990         default:
   984             ASSERT(0);
   991             ASSERT(0);
   985             return EFalse;//-- get rid of warning
   992             return EFalse;//-- get rid of warning
   986         };
   993         };
   987 	
   994     
   988     if (ret)
   995     if (ret)
   989         {
   996         {
   990 		aCluster=nextCluster;
   997         aCluster=nextCluster;
   991 	    }
   998         }
   992 	
   999     
   993     return ret;
  1000     return ret;
   994 
  1001 
   995     }
  1002     }
   996 
  1003 
   997 /**
  1004 /**
   998 Write EOF to aFatIndex
  1005 Write EOF to aFatIndex
   999     @param aFatIndex index in FAT (cluster number) to be written
  1006     @param aFatIndex index in FAT (cluster number) to be written
  1000 */
  1007 */
  1001 void CFatTable::WriteFatEntryEofL(TUint32 aFatIndex)
  1008 void CFatTable::WriteFatEntryEofL(TUint32 aFatIndex)
  1002 	{
  1009     {
  1003 	__PRINT1(_L("CAtaFatTable::WriteFatEntryEofL(%d)"), aFatIndex);
  1010     __PRINT1(_L("CAtaFatTable::WriteFatEntryEofL(%d)"), aFatIndex);
  1004 
  1011 
  1005     //-- use EOF_16Bit (0x0ffff) for all types of FAT, FAT cache will mask it appropriately
  1012     //-- use EOF_16Bit (0x0ffff) for all types of FAT, FAT cache will mask it appropriately
  1006     WriteL(aFatIndex, EOF_16Bit);
  1013     WriteL(aFatIndex, EOF_16Bit);
  1007 	}
  1014     }
  1008 
  1015 
  1009 
  1016 
  1010 
  1017 
  1011 /** 
  1018 /** 
  1012     Mark cluster number aFatIndex in FAT as bad 
  1019     Mark cluster number aFatIndex in FAT as bad 
  1018 
  1025 
  1019     //-- use KBad_16Bit (0x0fff7) for all types of FAT, FAT cache will mask it appropriately
  1026     //-- use KBad_16Bit (0x0fff7) for all types of FAT, FAT cache will mask it appropriately
  1020     WriteL(aFatIndex, KBad_16Bit);
  1027     WriteL(aFatIndex, KBad_16Bit);
  1021     
  1028     
  1022     FlushL();
  1029     FlushL();
  1023 	}
  1030     }
  1024 
  1031 
  1025 
  1032 
  1026 /**
  1033 /**
  1027 Return the location of a Cluster in the data section of the media
  1034 Return the location of a Cluster in the data section of the media
  1028 
  1035 
  1029 @param aCluster to find location of
  1036 @param aCluster to find location of
  1030 @return Byte offset of the cluster data 
  1037 @return Byte offset of the cluster data 
  1031 */
  1038 */
  1032 TInt64 CAtaFatTable::DataPositionInBytes(TUint32 aCluster) const
  1039 TInt64 CAtaFatTable::DataPositionInBytes(TUint32 aCluster) const
  1033 	{
  1040     {
  1034     __ASSERT_DEBUG(ClusterNumberValid(aCluster), Fault(EFatTable_InvalidIndex));
  1041     __ASSERT_DEBUG(ClusterNumberValid(aCluster), Fault(EFatTable_InvalidIndex));
  1035 
  1042 
  1036     const TInt clusterBasePosition=iOwner->ClusterBasePosition();
  1043     const TInt clusterBasePosition=iOwner->ClusterBasePosition();
  1037 	return(((TInt64(aCluster)-KFatFirstSearchCluster) << iOwner->ClusterSizeLog2()) + clusterBasePosition);
  1044     return(((TInt64(aCluster)-KFatFirstSearchCluster) << iOwner->ClusterSizeLog2()) + clusterBasePosition);
  1038 	}
  1045     }
  1039 
  1046 
  1040 
  1047 
  1041 
  1048 
  1042 
  1049 
  1043 
  1050 
  1044 
  1051