userlibandfileserver/fileserver/sfat32/fat_table32.cpp
branchRCL_3
changeset 294 039a3e647356
parent 268 345b1ca54e88
equal deleted inserted replaced
268:345b1ca54e88 294:039a3e647356
   400 
   400 
   401 /**
   401 /**
   402     Notify the media drive about media areas that shall be treated as "deleted" if this feature is supported.
   402     Notify the media drive about media areas that shall be treated as "deleted" if this feature is supported.
   403     @param aFreedClusters array with FAT numbers of clusters that shall be marked as "deleted"
   403     @param aFreedClusters array with FAT numbers of clusters that shall be marked as "deleted"
   404 */
   404 */
   405 void CFatTable::DoFreedClustersNotifyL(RClusterArray &aFreedClusters)
   405 void CFatTable::DoFreedClustersNotify(RClusterArray &aFreedClusters)
   406 {
   406 {
   407     ASSERT(iMediaAtt & KMediaAttDeleteNotify);
   407     ASSERT(iMediaAtt & KMediaAttDeleteNotify);
   408 
   408 
   409     const TUint clusterCount = aFreedClusters.Count();
   409     const TUint clusterCount = aFreedClusters.Count();
   410 
   410 
   421 	for (TUint i=0; i<clusterCount; ++i)
   421 	for (TUint i=0; i<clusterCount; ++i)
   422 	{
   422 	{
   423         const TUint currCluster = aFreedClusters[i];
   423         const TUint currCluster = aFreedClusters[i];
   424         
   424         
   425         if (deleteLen == 0)
   425         if (deleteLen == 0)
   426 		    byteAddress = DataPositionInBytesL(currCluster); //-- start of the media range
   426 		    byteAddress = DataPositionInBytes(currCluster); //-- start of the media range
   427         
   427         
   428         deleteLen += bytesPerCluster;
   428         deleteLen += bytesPerCluster;
   429 
   429 
   430         //-- if this is the last entry in the array or the net cluster number is not consecutive, notify the driver
   430         //-- if this is the last entry in the array or the net cluster number is not consecutive, notify the driver
   431 		if ((i+1) == clusterCount || aFreedClusters[i+1] != (currCluster+1))
   431 		if ((i+1) == clusterCount || aFreedClusters[i+1] != (currCluster+1))
   436             const TInt r = iOwner->LocalDrive()->DeleteNotify(byteAddress, deleteLen);
   436             const TInt r = iOwner->LocalDrive()->DeleteNotify(byteAddress, deleteLen);
   437 			if(r != KErrNone)
   437 			if(r != KErrNone)
   438                 {//-- if DeleteNotify() failed, it means that something terribly wrong happened to the NAND media; 
   438                 {//-- if DeleteNotify() failed, it means that something terribly wrong happened to the NAND media; 
   439                  //-- in normal circumstances it can not happen. One of the reasons: totally worn out media.
   439                  //-- in normal circumstances it can not happen. One of the reasons: totally worn out media.
   440                 const TBool platSecEnabled = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement);
   440                 const TBool platSecEnabled = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement);
   441                 __PRINT3(_L("CFatTable::DoFreedClustersNotifyL() DeleteNotify failure! drv:%d err:%d, PlatSec:%d"),iOwner->DriveNumber(), r, platSecEnabled);
   441                 __PRINT3(_L("CFatTable::DoFreedClustersNotify() DeleteNotify failure! drv:%d err:%d, PlatSec:%d"),iOwner->DriveNumber(), r, platSecEnabled);
   442 
   442 
   443                 if(platSecEnabled)
   443                 if(platSecEnabled)
   444                     {
   444                     {
   445                     //-- if PlatSec is enabled, we can't afford jeopardize the security; without DeleteNotify()
   445                     //-- if PlatSec is enabled, we can't afford jeopardize the security; without DeleteNotify()
   446                     //-- it's possible to pick up data from deleted files, so, panic the file server.
   446                     //-- it's possible to pick up data from deleted files, so, panic the file server.
   519         {//-- reached a limit of the entries in the array. Flush FAT cache, notify the driver and empty the array.
   519         {//-- reached a limit of the entries in the array. Flush FAT cache, notify the driver and empty the array.
   520             IncrementFreeClusterCount(cntFreedClusters);
   520             IncrementFreeClusterCount(cntFreedClusters);
   521             cntFreedClusters = 0;
   521             cntFreedClusters = 0;
   522 
   522 
   523             SetFreeClusterHint(lastKnownFreeCluster);
   523             SetFreeClusterHint(lastKnownFreeCluster);
   524             DoFreedClustersNotifyL(deletedClusters);
   524             DoFreedClustersNotify(deletedClusters);
   525         }
   525         }
   526 
   526 
   527     }
   527     }
   528 
   528 
   529     //-- increase the number of free clusters and notify the driver if required.
   529     //-- increase the number of free clusters and notify the driver if required.
   530     IncrementFreeClusterCount(cntFreedClusters);
   530     IncrementFreeClusterCount(cntFreedClusters);
   531     SetFreeClusterHint(lastKnownFreeCluster);
   531     SetFreeClusterHint(lastKnownFreeCluster);
   532     
   532     
   533     if(bFreeClustersNotify)
   533     if(bFreeClustersNotify)
   534         DoFreedClustersNotifyL(deletedClusters);
   534         DoFreedClustersNotify(deletedClusters);
   535 
   535 
   536 	CleanupStack::PopAndDestroy(&deletedClusters);
   536 	CleanupStack::PopAndDestroy(&deletedClusters);
   537 	}
   537 	}
   538 
   538 
   539 //-----------------------------------------------------------------------------
   539 //-----------------------------------------------------------------------------
   669     //__PRINT1(_L("#- CFatTable::RequestFreeClusters(%d)"),aClustersRequired);
   669     //__PRINT1(_L("#- CFatTable::RequestFreeClusters(%d)"),aClustersRequired);
   670     ASSERT(aClustersRequired >0);
   670     ASSERT(aClustersRequired >0);
   671     return (NumberOfFreeClusters() >= aClustersRequired);
   671     return (NumberOfFreeClusters() >= aClustersRequired);
   672     }
   672     }
   673 
   673 
       
   674 //-----------------------------------------------------------------------------
       
   675 /**
       
   676     @return ETrue if the cluster number aClusterNo is valid, i.e. belongs to the FAT table
       
   677 */
       
   678 TBool CFatTable::ClusterNumberValid(TUint32 aClusterNo) const 
       
   679     {
       
   680     return (aClusterNo >= KFatFirstSearchCluster) && (aClusterNo < iMaxEntries); 
       
   681     }
   674     
   682     
   675 
   683 
   676 
   684 
   677 //#######################################################################################################################################
   685 //#######################################################################################################################################
   678 //#     CAtaFatTable class implementation 
   686 //#     CAtaFatTable class implementation 
  1034         if(pFatBitCache)
  1042         if(pFatBitCache)
  1035             {//-- bit cache is present, we need to populate (or repopulate it)
  1043             {//-- bit cache is present, we need to populate (or repopulate it)
  1036             //-- create helper thread object and start the thread
  1044             //-- create helper thread object and start the thread
  1037             ipHelperThread = CFat32BitCachePopulator::NewL(*this);
  1045             ipHelperThread = CFat32BitCachePopulator::NewL(*this);
  1038 
  1046 
  1039             if(ipHelperThread->Launch() != KErrNone)
  1047             ipHelperThread->Launch(); 
  1040                 {//-- failed for some reason
       
  1041                 DestroyHelperThread();
       
  1042                 }
       
  1043                 else
       
  1044                 {
       
  1045             //-- background FAT bit cache populating thread is running now.
  1048             //-- background FAT bit cache populating thread is running now.
  1046             //-- the result of thread start up and completion isn't very interesting: If it fails to 
  1049             //-- the result of thread start up and completion isn't very interesting: If it fails to 
  1047             //-- properly populate the cache, nothing fatal will happen.
  1050             //-- properly populate the cache, nothing fatal will happen.
  1048             }
       
  1049             }
  1051             }
  1050 
  1052 
  1051         //-- CFat32BitCachePopulator doesn't affect FAT table state. 
  1053         //-- CFat32BitCachePopulator doesn't affect FAT table state. 
  1052         SetState(EMounted);
  1054         SetState(EMounted);
  1053         return; 
  1055         return; 
  1476                 TInt nMntDebugFlags;
  1478                 TInt nMntDebugFlags;
  1477                 if(bFat32BkGndScan && RProperty::Get(KSID_Test1, iOwner->DriveNumber(), nMntDebugFlags) == KErrNone)
  1479                 if(bFat32BkGndScan && RProperty::Get(KSID_Test1, iOwner->DriveNumber(), nMntDebugFlags) == KErrNone)
  1478                 {//-- test property for this drive is defined
  1480                 {//-- test property for this drive is defined
  1479                     if(nMntDebugFlags & KMntDisable_FatBkGndScan)
  1481                     if(nMntDebugFlags & KMntDisable_FatBkGndScan)
  1480                     {
  1482                     {
  1481                     __PRINT(_L("#- FAT32 BkGnd scan is disabled by debug interface."));
  1483                     __PRINT(_L("#- FAT32 BkGnd scan is disabled is disabled by debug interface."));
  1482                     bFat32BkGndScan = EFalse;
  1484                     bFat32BkGndScan = EFalse;
  1483                     }
  1485                     }
  1484             
  1486             
  1485                 }
  1487                 }
  1486 #endif
  1488 #endif
  1540     //-- 2. create helper thread object and start the thread
  1542     //-- 2. create helper thread object and start the thread
  1541     ipHelperThread = CFat32FreeSpaceScanner::NewL(*this);
  1543     ipHelperThread = CFat32FreeSpaceScanner::NewL(*this);
  1542     
  1544     
  1543     SetState(EFreeClustersScan);
  1545     SetState(EFreeClustersScan);
  1544     
  1546     
  1545     User::LeaveIfError(ipHelperThread->Launch()); 
  1547     ipHelperThread->Launch(); 
  1546     
       
  1547     //-- background FAT scanning thread is running now
  1548     //-- background FAT scanning thread is running now
  1548     }
  1549     }
  1549 
  1550 
  1550 //-----------------------------------------------------------------------------
  1551 //-----------------------------------------------------------------------------
  1551 /**
  1552 /**
  1786     FlushL();
  1787     FlushL();
  1787 	}
  1788 	}
  1788 
  1789 
  1789 
  1790 
  1790 /**
  1791 /**
  1791     Return media position in bytes of the cluster start
  1792     Return the location of a Cluster in the data section of the media
  1792 
  1793 
  1793     @param aCluster to find location of
  1794     @param aCluster to find location of
  1794     @return Byte offset of the cluster data 
  1795     @return Byte offset of the cluster data 
  1795 */
  1796 */
  1796 TInt64 CAtaFatTable::DataPositionInBytesL(TUint32 aCluster) const
  1797 TInt64 CAtaFatTable::DataPositionInBytes(TUint32 aCluster) const
  1797 	{
  1798 	{
  1798     if(!ClusterNumberValid(aCluster))
  1799 
  1799         {
  1800     __ASSERT_DEBUG(ClusterNumberValid(aCluster), Fault(EFatTable_InvalidIndex));
  1800         __ASSERT_DEBUG(0, Fault(EFatTable_InvalidIndex));
  1801 
  1801         User::Leave(KErrCorrupt);
  1802     const TInt clusterBasePosition=iOwner->ClusterBasePosition();
  1802         }
       
  1803 
       
  1804     const TUint32 clusterBasePosition=iOwner->ClusterBasePosition();
       
  1805 	return(((TInt64(aCluster)-KFatFirstSearchCluster) << iOwner->ClusterSizeLog2()) + clusterBasePosition);
  1803 	return(((TInt64(aCluster)-KFatFirstSearchCluster) << iOwner->ClusterSizeLog2()) + clusterBasePosition);
  1806 	}
  1804 	}
  1807 
  1805 
  1808 
  1806 
  1809 
  1807 
  1983 
  1981 
  1984 //-----------------------------------------------------------------------------
  1982 //-----------------------------------------------------------------------------
  1985 
  1983 
  1986 /**
  1984 /**
  1987     Launches the FAT32_ScanThread scaner thread.
  1985     Launches the FAT32_ScanThread scaner thread.
  1988     @return  KErrNone if the thread launched OK
  1986     @return  standard error code
  1989              standard error code otherwise
       
  1990 */
  1987 */
  1991 TInt CFat32ScanThread::Launch()
  1988 TInt CFat32ScanThread::Launch()
  1992     {
  1989     {
  1993     return DoLaunchThread(FAT32_ScanThread, this);    
  1990     return DoLaunchThread(FAT32_ScanThread, this);    
  1994     }
  1991     }
  2546 
  2543 
  2547 
  2544 
  2548             //-- allow this thread to be preempted by another one that wants to access the media driver.
  2545             //-- allow this thread to be preempted by another one that wants to access the media driver.
  2549             //-- without this wait we will have priority inversion, because this (low priority) thread continiously reads data by big chunks 
  2546             //-- without this wait we will have priority inversion, because this (low priority) thread continiously reads data by big chunks 
  2550             //-- and doesn't allow others to access the driver.
  2547             //-- and doesn't allow others to access the driver.
  2551             //-- On the other hand, if the thread's priority is boosted, there is no reason to be so polite.
  2548             //-- On the other hand, if the thread's priority is boosted, there is no reason to be polite.
  2552             if(!pSelf->IsPriorityBoosted())
  2549             if(!pSelf->IsPriorityBoosted())
  2553                 {//-- User::After() granularity can be much coarser than 1ms, e.g. 1/64 Sec. This will add up to the scanning time
  2550                 User::After(K1mSec); //-- User::After() granularity can be much coarser than 1ms
  2554                 User::After(K1mSec); 
       
  2555                 }
       
  2556             else
       
  2557                 {//-- use much less coarse granularity to allow this thread to be preempted even if its priority is boosted.
       
  2558                 User::AfterHighRes(128); 
       
  2559                 }
       
  2560 
  2551 
  2561             //-------------------------------------------
  2552             //-------------------------------------------
  2562             mediaPos += bytesToRead;
  2553             mediaPos += bytesToRead;
  2563             rem -= bytesToRead;
  2554             rem -= bytesToRead;
  2564         
  2555