--- a/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Tue Jan 19 13:48:03 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Mon Jan 18 21:31:10 2010 +0200
@@ -29,9 +29,6 @@
TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively);
-static void MarkClusterVisited(RBitVector& aFatBitVec, TUint32 aCluster);
-static TBool IsClusterVisited(const RBitVector& aFatBitVec, TUint32 aCluster);
-static TInt NextUnvisitedCluster(const RBitVector& aFatBitVec, TUint32 aCluster);
//-----------------------------------------------------------------------------------------
@@ -2507,7 +2504,8 @@
//-- while directory cache pages are. For FAT32 it doesn't matter, because root dir is a usual file.
//-- the "rummage dir. cache" can be swithed off. This is not affecting the functionality, only the performance.
- #if 1
+ #ifdef USE_DIR_CACHE_RUMMAGE
+
if(iRawDisk->DirCacheInterface() && trgNameFullySpecified && !IsRootDir(aDosEntryPos) && !aFileCreationHelper)
{//-- aName is fully specified, i.e doesn't contain wildcards
@@ -4122,10 +4120,12 @@
TRAPD(err,GetDosEntryFromNameL(aName,dosEntryPos,dosEntry));
if(err!=KErrNone)
return err;
+
TInt startCluster=StartCluster(dosEntry);
// Empty files will return a cluster of zero
if(startCluster==0)
return KErrEof;
+
aUniqueId=MAKE_TINT64(0,startCluster);
return KErrNone;
}
@@ -4149,154 +4149,10 @@
//-----------------------------------------------------------------------------------------
-//-- maximal level of recursion for the CheckDisk. i.e. the max. number of folded directories to check.
-const TInt KCheckDskMaxRecursionLevel = 50;
-
-//
-// Walks a directory cluster list then checks all the entries.
-//
-void CFatMountCB::ChkDirL(RBitVector& aFatBitVec, TInt aDirCluster)
- {
- //__PRINT1(_L("### CFatMountCB::ChkDirL() level:%d"),iChkDiscRecLevel);
-
- //-- check if we have reached the recursion limit. on hardware the stack is very limited
- //-- and its overflow will lead to crash.
- if(iChkDiscRecLevel++ >= KCheckDskMaxRecursionLevel)
- {
- __PRINT1(_L("CFatMountCB::ChkDirL() max recursion level(%d) reached. Leaving!"),iChkDiscRecLevel);
- User::Leave(KErrTooBig);
- }
-
- if(/*Is32BitFat() &&*/aDirCluster != 0 && (aDirCluster == RootIndicator()))//the bit in comments maybe required
- WalkClusterListL(aFatBitVec, RootIndicator());
-
- TEntryPos entryPos(aDirCluster,0);
- FOREVER
- {
- TFatDirEntry entry;
- ReadDirEntryL(entryPos,entry);
- MoveToDosEntryL(entryPos,entry);
- if (entry.IsEndOfDirectory())
- break;
- if (IsRootDir(entryPos)&&(StartOfRootDirInBytes()+entryPos.iPos==(RootDirEnd()-KSizeOfFatDirEntry)))
- {
- if(!entry.IsErased())
- ChkEntryL(aFatBitVec, entry);
- break; // Allows maximum number of entries in root directory
- }
- MoveToNextEntryL(entryPos);
- if (entry.IsParentDirectory() || entry.IsCurrentDirectory() || entry.IsErased())
- continue;
- ChkEntryL(aFatBitVec, entry);
- }
-
- iChkDiscRecLevel--;
- }
-
-//-----------------------------------------------------------------------------------------
-
-//
-// Check FAT is valid for anEntry
-//
-void CFatMountCB::ChkEntryL(RBitVector& aFatBitVec, const TFatDirEntry& anEntry)
- {
- TInt listLength=0;
-
- if ((anEntry.Attributes()&(KEntryAttDir)) || anEntry.Size())
- listLength=WalkClusterListL(aFatBitVec, StartCluster(anEntry));
- else if (anEntry.StartCluster() != 0) // zero length file
- User::Leave(EFatChkDskInvalidEntrySize); // shouldn't have clusters
-
- if (anEntry.Attributes()&KEntryAttDir)
- ChkDirL(aFatBitVec, StartCluster(anEntry));
-
- // Check that the correct number of clusters have been allocated for the size of the file.
-
- else if ((anEntry.Attributes()&KEntryAttVolume)==0)
- {
- TInt clustersForFileSize;
- TInt clusterSize=1<<ClusterSizeLog2();
- clustersForFileSize = (TInt) ( (TInt64(anEntry.Size()) + TInt64(clusterSize-1)) >> ClusterSizeLog2() );
-
- if (listLength!=clustersForFileSize)
- User::Leave(EFatChkDskInvalidEntrySize);
- }
- }
-
-//-----------------------------------------------------------------------------------------
-
-//
-// Walks cluster list from aCluster to EOF
-// Reports an error if an invalid cluster is found before EOF or
-// a cluster has been visited before.
-//
-TInt CFatMountCB::WalkClusterListL(RBitVector& aFatBitVec, TInt aCluster)
- {
-
- TInt i=0;
- do {
- i++;
- if (!ValidClusterNumber(aCluster))
- {
- __PRINT1(_L("Bad Cluster number %d"),aCluster);
- User::Leave(EFatChkDskIllegalClusterNumber);
- }
-
- if (IsClusterVisited(aFatBitVec, aCluster))
- {
- __PRINT1(_L("Cluster already in use %d"),aCluster);
- User::Leave(EFatChkDskClusterAlreadyInUse);
- }
-
- MarkClusterVisited(aFatBitVec, aCluster);
-
- } while (FAT().GetNextClusterL(aCluster));
-
- return(i);
- }
-
-//-----------------------------------------------------------------------------------------
-
-//
-// Checks that all unvisited clusters are marked as free in the FAT
-//
-void CFatMountCB::CheckUnvisitedClustersL(const RBitVector& aFatBitVec) const
- {
-
- TInt cluster=2;
- TInt maxCluster=cluster + UsableClusters();
- while (cluster<maxCluster)
- {
- cluster=NextUnvisitedCluster(aFatBitVec, cluster); //-- move to the next unvisited cluster
- if(cluster < 0 || cluster >= maxCluster)
- break;
-
- TInt clusterVal=FAT().ReadL(cluster);
- if (clusterVal!=0 && IsEndOfClusterCh(clusterVal)==EFalse && !IsBadCluster(clusterVal))
- {
- __PRINT1(_L("\n*****Bad cluster Num = %d"),cluster);
- User::Leave(EFatChkDskBadCluster);
- }
- }
- }
-
-//-----------------------------------------------------------------------------------------
-
-/**
-@param aCluster cluster number to check for validity
-@returns ETrue if aCluster is a valid cluster number
+/**
+ Check file system for errors.
+ @return KErrNone if no errors found, otherwise a error code hopefully describing the problem found.
*/
-TBool CFatMountCB::ValidClusterNumber(TUint32 aCluster) const
- {
- return (aCluster>=KFatFirstSearchCluster && aCluster<=MaxClusterNumber());
- }
-
-//-----------------------------------------------------------------------------------------
-
-//
-// Walk the FAT, returns error if find an unterminated list or
-// lists that merge.
-//
TInt CFatMountCB::CheckDisk()
{
@@ -4307,10 +4163,6 @@
//-- create a bit representation of the FAT
const TUint32 MaxClusters = UsableClusters()+KFatFirstSearchCluster; //-- UsableClusters() doesn't count first 2 unused clusers
-
-
- // cluster count may be zero if boot sector failed to be read (e.g. if the media is locked)
- // or if TDrive::MountMedia(ETrue) has been called (in which case the boot sector may
if (MaxClusters == 0)
return KErrCorrupt;
@@ -4319,115 +4171,42 @@
TTime timeEnd;
timeStart.UniversalTime(); //-- take start time
-
- RBitVector bitVec; //-- each bit in this vector represents a FAT cluster
-
- TInt nRes = bitVec.Create(MaxClusters);
+ TInt nRes;
+
+ CScanDrive* pScnDrv = NULL;
+ TRAP(nRes, pScnDrv=CScanDrive::NewL(this));
if(nRes != KErrNone)
- {
- ASSERT(nRes == KErrNoMemory); //-- the only one possible reason.
- return KErrNoMemory;
- }
-
- iChkDiscRecLevel = 0; //-- reset CheckDisk recursion counter
- TRAPD(r,ChkDirL(bitVec, RootIndicator())); // Check from root directory
- if (r==KErrNone)
- {
- TRAP(r,CheckUnvisitedClustersL(bitVec));
- }
-
-
- bitVec.Close();
-
+ return nRes;
+
+ //-- start ScanDrive in "checkdisk" mode
+ TRAPD(nScnDrvRes, pScnDrv->StartL(CScanDrive::ECheckDisk));
+
timeEnd.UniversalTime(); //-- take end time
const TInt msScanTime = (TInt)( (timeEnd.MicroSecondsFrom(timeStart)).Int64() / K1mSec);
(void)msScanTime;
-
__PRINT1(_L("#@@@ CheckDisk() time taken:%d ms"), msScanTime);
-
-
- switch(r)
+
+ CScanDrive::TGenericError chkDskRes = pScnDrv->ProblemsDiscovered();
+ const TBool bProblemsFound = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
+
+ if(bProblemsFound && chkDskRes == CScanDrive::ENoErrors)
+ {//-- ScanDrive in this mode can leave unexpectedly without setting an error code that is returned by ProblemsDiscovered();
+ //-- leave itself means a problem
+ chkDskRes = CScanDrive::EUnknownError;
+ }
+
+ delete pScnDrv;
+
+ if(chkDskRes != KErrNone)
{
-
- case KErrNone:
- return KErrNone;
-
- case EFatChkDskIllegalClusterNumber:
- return(1);
-
- case EFatChkDskClusterAlreadyInUse:
- return(2);
-
- case EFatChkDskBadCluster:
- return(3);
-
- case EFatChkDskInvalidEntrySize:
- return(4);
-
- default:
- break;
+ __PRINT2(_L("CFatMountCB::CheckDisk() drv:%d, result:%d"), DriveNumber(), chkDskRes);
}
-
- return(r);
+
+ return chkDskRes;
+
}
-//-----------------------------------------------------------------------------------------
-// Helper functions for Check Disk functionality
-//-----------------------------------------------------------------------------------------
-
-/**
- Find the next unvisited cluster number in the bit array.
-
- @param aBitList bit array, where '0' bits represent unvisited clusters.
- @param aCluster cluster number to start search with.
-
- @return positive integer indicating next unvisited cluster number
- KErrNotFound (-1) if there are no unvisited clusters
-
-*/
-static TInt NextUnvisitedCluster(const RBitVector& aFatBitVec, TUint32 aCluster)
-{
- __ASSERT_DEBUG(aCluster >= KFatFirstSearchCluster, Fault(EFatChkDskIllegalClusterNumber)); //-- 1st 2 FAT entries are reserved
-
- TUint32 searchPos = aCluster; //-- bit number to start search with
-
- //-- look for the unvisited cluster (bit '0') in the bit array from the searchPos to the right
- if(aFatBitVec.Find(searchPos, 0, RBitVector::ERight))
- return searchPos;
-
- return KErrNotFound;
-}
-
-
-/**
- Check if we have visited cluster aCluster
-
- @param aFatBitVec bit array, where '0' bits represent unvisited clusters.
- @param aCluster cluster number to check
- @return ETrue if aCluster has been visited.
-*/
-static TBool IsClusterVisited(const RBitVector& aFatBitVec, TUint32 aCluster)
-{
- __ASSERT_DEBUG(aCluster >= KFatFirstSearchCluster, Fault(EFatChkDskIllegalClusterNumber)); //-- 1st 2 FAT entries are reserved
-
- return aFatBitVec[aCluster];
-}
-
-/**
- Mark aCluster as visited
- @param aFatBitVec bit array, where '0' bits represent unvisited clusters.
- @param aCluster cluster number to mark
-*/
-static void MarkClusterVisited(RBitVector& aFatBitVec, TUint32 aCluster)
-{
- __ASSERT_DEBUG(aCluster >= KFatFirstSearchCluster, Fault(EFatChkDskIllegalClusterNumber)); //-- 1st 2 FAT entries are reserved
-
- aFatBitVec.SetBit(aCluster); //-- '1' bit in a bit array means that the corresponding cluster is visited
-}
-
-
-
//-------------------------------------------------------------------------------------------------------------------
/**
@@ -4442,7 +4221,7 @@
if(nRes != KErrNone)
return nRes;
- TRAPD(nScnDrvRes, pScnDrv->StartL());
+ TRAPD(nScnDrvRes, pScnDrv->StartL(CScanDrive::EScanAndFix));
const TBool bNeedFatRemount = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
delete pScnDrv;
@@ -4459,7 +4238,7 @@
return nScnDrvRes;
- //-- if ScanDrive hasn't found anything wrong or has fixed recoverable erros, mark the volume clean
+ //-- if ScanDrive hasn't found anything wrong or has fixed recoverable errors, mark the volume clean
if(VolCleanFlagSupported())
{
//-- if there is a background FAT scanning thread, we need to wait until it finishes its work.