diff -r a179b74831c9 -r c1f20ce4abcf userlibandfileserver/fileserver/sfat32/sl_mnt.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Thu Aug 19 11:14:22 2010 +0300 +++ b/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Tue Aug 31 16:34:26 2010 +0300 @@ -26,6 +26,7 @@ #include "sl_dir_cache.h" #include "sl_scandrv.h" #include +#include TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively); @@ -550,10 +551,8 @@ return; } - if(LockStatus() != 0) - {//-- can't finalise the volume if it has opened objects and not in the consistent state. - //-- Theoretically, we can finalise the mount if we have files opened only for read, but at present, - //-- it's impossible to detect such situation. + if(Locked()) + {//-- can't finalise the volume if it has opened disk access objects, like Format or RawAccess User::Leave(KErrInUse); } @@ -612,10 +611,23 @@ */ TBool CFatMountCB::VolCleanFlagSupported() const { - const TFatType fatType=FatType(); - - ASSERT(fatType == EFat12 || fatType == EFat16 || fatType == EFat32); - return (fatType != EFat12); + const TFatType fatType=FatType(); + + ASSERT(fatType == EFat12 || fatType == EFat16 || fatType == EFat32); + return (fatType != EFat12); + } + + +//----------------------------------------------------------------------------------------- +/** + @return Volume size in bytes according to the number of usable clusters. + This approach is not applicable to RAM drive, because its size isn't fixed and can be adjusted by the system. +*/ +TUint64 CFatMountCB::VolumeSizeInBytes() const + { + ASSERT(ConsistentState()); + ASSERT(!iRamDrive); + return ((TUint64)UsableClusters()) << ClusterSizeLog2(); } //----------------------------------------------------------------------------------------- @@ -680,16 +692,21 @@ const TUint32 freeClusters = FAT().NumberOfFreeClusters(bSyncOp); - + aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2(); __PRINT1(_L("CFatMountCB::VolumeL() free clusters:%d"), freeClusters); - aVolume.iFree = (TInt64)freeClusters << ClusterSizeLog2(); - - if (drvInfo.iType==EMediaRam) + + if(drvInfo.iType==EMediaRam) + {//-- a special case. RAM drive size is variable and adjustable. It should be calculated from aVolume.iFree and CMountCB::iFree + ASSERT(iRamDrive); aVolume.iSize=aVolume.iFree+iSize; - - aVolume.iSize-=ClusterBasePosition(); // Allow for bytes used by FAT etc - aVolume.iSize=(aVolume.iSize >> ClusterSizeLog2()) << ClusterSizeLog2(); //-- round down to cluster size + aVolume.iSize-=ClusterBasePosition(); // Allow for bytes used by FAT etc + aVolume.iSize=(aVolume.iSize >> ClusterSizeLog2()) << ClusterSizeLog2(); //-- round down to cluster size + } + else + {//-- normal case; the volume size is determined by amount of usable clusters + aVolume.iSize = VolumeSizeInBytes(); + } } @@ -1622,7 +1639,7 @@ const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); const TInt writeLength=Min(aLength,(clusterListLen<WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag)); @@ -1653,7 +1670,7 @@ if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster)) { //Copy the contents already present in this cluster to new cluster allocated. const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2()); - dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead)); + dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead)); //-- Allocate the buffer required to copy the contents from bad cluster @@ -1682,7 +1699,7 @@ { //Calculate and copy the contents to new cluster. aPos.iCluster = goodcluster; - dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead); + dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead); r = LocalDrive()->Write(dataStart, clustBuf); if(r == KErrNone) @@ -1790,7 +1807,7 @@ const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); const TInt readLength=Min(aLength,(clusterListLen<ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag)); @@ -3154,7 +3171,7 @@ User::Leave(KErrCorrupt); TBuf8 uidBuf; - iRawDisk->ReadCachedL(FAT().DataPositionInBytesL(aCluster),sizeof(TCheckedUid),uidBuf); + iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf); __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed)); TCheckedUid uid(uidBuf); anEntry.iType=uid.UidType(); @@ -3230,7 +3247,7 @@ // Read the remaining length or the entire cluster block whichever is smaller TInt readLength = Min(aLength-readTotal,(clusterListLen<0,Fault(EReadFileSectionFailed)); - TInt64 dataAddress=(FAT().DataPositionInBytesL(cluster))+pos; + TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos; iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0); readTotal += readLength; @@ -3434,7 +3451,7 @@ if (!IsRootDir(aPos)) { TInt relPos=ClusterRelativePos(aPos.iPos); - return FAT().DataPositionInBytesL(aPos.iCluster)+relPos; + return FAT().DataPositionInBytes(aPos.iCluster)+relPos; } if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()) User::Leave(KErrDirFull); // Past last root dir entry @@ -3626,23 +3643,36 @@ case EDisableFATDirCache: { MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface(); - TUint32 KEDisableFATDirCache = CDynamicDirCache::EDisableCache; + TUint32 KEDisableFATDirCache = MWTCacheInterface::EDisableCache; pDirCache->Control(KEDisableFATDirCache, (TUint32) aParam1, NULL); break; } case EDumpFATDirCache: { MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface(); - TUint32 KEDumpFATDirCache = CDynamicDirCache::EDumpCache; - pDirCache->Control(KEDumpFATDirCache, 0, NULL); + if (pDirCache) + { + TUint32 KEDumpFATDirCache = MWTCacheInterface::EDumpCache; + pDirCache->Control(KEDumpFATDirCache, 0, NULL); + } break; } case EFATDirCacheInfo: { - MWTCacheInterface* pDirCache = iRawDisk->DirCacheInterface(); - TUint32 KEFATDirCacheInfo = CDynamicDirCache::ECacheInfo; - pDirCache->Control(KEFATDirCacheInfo, 0, NULL); - break; + MWTCacheInterface* pDCache = iRawDisk->DirCacheInterface(); + if (pDCache) + { + TUint32 KEFATDirCacheInfo = MWTCacheInterface::ECacheInfo; + TDirCacheInfo aInfo; + TInt r = pDCache->Control(KEFATDirCacheInfo, 0, static_cast(&aInfo)); + if (r == KErrNone) + { + TPckgBuf pkgBuf(aInfo); + r = aMessage.Write(2,pkgBuf); + } + return r; + } + return KErrNotSupported; } @@ -4070,7 +4100,7 @@ User::LeaveIfError(r); if ( caps().iType&EMediaRam ) { - realPosition = FAT().DataPositionInBytesL( aPos.iCluster ); + realPosition = FAT().DataPositionInBytes( aPos.iCluster ); aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2()); blockMapEntry.SetStartBlock( aPos.iCluster ); } @@ -4183,7 +4213,7 @@ 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; + chkDskRes = nScnDrvRes == KErrNone ? CScanDrive::EUnknownError : (CScanDrive::TGenericError) nScnDrvRes; } delete pScnDrv; @@ -4263,7 +4293,7 @@ TInt nRes; if(LockStatus()!=0) - { + {//-- can't run if the volume has opened objects, like files, directories, formats etc. __PRINT(_L("CFatMountCB::ScanDrive() locked!\n")); return KErrInUse; }