--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfat/sl_disk.cpp Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,502 @@
+// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// f32\sfat\sl_disk.cpp
+//
+//
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!
+//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
+//!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#include "sl_disk.h"
+#include "sl_cache.h"
+#include "sl_dir_cache.h"
+
+/**
+@file
+*/
+
+
+//################################################################################################################################
+//# CRawDisk implementation
+//################################################################################################################################
+
+
+/**
+ Factory function. Constructs objects of the classes derived from CRawDisk.
+
+ @param aOwner reference to the onwning FAT Mount class
+ @param aLocDrvCaps local drive capabilities from the media driver
+ @return pointer to the constructed object. May be NULL on error.
+*/
+CRawDisk* CRawDisk::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps)
+{
+ __PRINT1(_L("CRawDisk::NewL() drv:%d"), aOwner.DriveNumber());
+
+ if(aLocDrvCaps.iMediaAtt & KMediaAttVariableSize)
+ {//-- this is the RAM drive "attribute"
+ ASSERT((aLocDrvCaps.iDriveAtt & (KDriveAttInternal|KDriveAttLocal)) && aLocDrvCaps.iType == EMediaRam);
+ if(!aLocDrvCaps.iBaseAddress)
+ {
+ ASSERT(0);
+ return NULL;
+ }
+
+ return CRamDisk::NewL(aOwner);
+ }
+
+ //-- create CAtaDisk by default
+ return CAtaDisk::NewL(aOwner);
+}
+
+
+CRawDisk::CRawDisk(CFatMountCB& aOwner)
+ {
+ iFatMount = &aOwner;
+ }
+
+/**
+ Default implementation. Initialises and re-initialises the object.
+*/
+void CRawDisk::InitializeL()
+ {
+ ASSERT(iFatMount);
+ }
+
+
+TInt CRawDisk::GetLastErrorInfo(TDes8& /*aErrorInfo*/) const
+ {
+ return KErrNotSupported;
+ }
+
+//################################################################################################################################
+//## CAtaDisk class implementation
+//################################################################################################################################
+
+CAtaDisk::CAtaDisk(CFatMountCB& aFatMount)
+ :CRawDisk(aFatMount), iDrive(aFatMount.DriveInterface())
+ {
+ }
+
+CAtaDisk::~CAtaDisk()
+ {
+ delete ipDirCache;
+ delete iUidCache;
+
+ }
+
+
+//-------------------------------------------------------------------------------------
+
+/**
+ CAtaDisk factory method.
+
+ @param aFatMount reference to the owner.
+ @return pointer to the constructed object.
+*/
+CAtaDisk* CAtaDisk::NewL(CFatMountCB& aFatMount)
+ {
+ __PRINT1(_L("CAtaDisk::NewL() drv:%d"), aFatMount.DriveNumber());
+
+ CAtaDisk* pSelf = new (ELeave) CAtaDisk(aFatMount);
+
+ CleanupStack::PushL(pSelf);
+
+ pSelf->ConstructL();
+ pSelf->InitializeL();
+
+ CleanupStack::Pop();
+
+ return pSelf;
+ }
+
+//-------------------------------------------------------------------------------------
+
+/** 2nd stage constructor */
+void CAtaDisk::ConstructL()
+ {
+ //=========================== create data WT cache that is primarily used for caching exacutable modules' UIDs
+ const TUint32 KUidCachePageSzLog2 = 9; //-- 512 bytes in page
+ const TUint32 KUidCachePages = 64; //-- 64 pages; total cache size is 32K
+
+ iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2);
+
+
+ //=========================== create directory cache
+
+ //-- Get dir. cache parameters from config. They may be set in estart.txt for a specified drive.
+ const TUint32 KDirCacheSize = iFatMount->FatConfig().DirCacheSize(); //- Total directory cache size, bytes.
+ const TUint32 KMaxDirCachePageSzLog2 = iFatMount->FatConfig().DirCacheMaxPageSizeLog2(); //- Log2 of the Max. dir. cache page.
+
+ __PRINT2(_L("CAtaDisk::ConstructL() Dir Cache config:%d,%d"),KDirCacheSize,KMaxDirCachePageSzLog2);
+
+ ASSERT(KDirCacheSize >= K1KiloByte && KDirCacheSize <= K1MegaByte);
+ ASSERT((KMaxDirCachePageSzLog2 >= KDefSectorSzLog2) && (Pow2(KMaxDirCachePageSzLog2) <= KDirCacheSize));
+
+ //-- calculate the size and number of pages for the dir. cache.
+ //-- if the mount's cluster size is less than max. page size from config, the page size will be cluster size.
+ //-- otherwise it will be the value from config. I.e the minimal page size is cluster size; the maximal page size is taken from config.
+ //-- The number of pages depends on total cache size and page size.
+ const TUint clustSizeLog2 = iFatMount->ClusterSizeLog2(); //-- current FAT cluster size Log2
+ const TUint32 pageSzLog2 = (clustSizeLog2 <= KMaxDirCachePageSzLog2) ? clustSizeLog2 : KMaxDirCachePageSzLog2;
+ const TUint32 numPages = KDirCacheSize / (Pow2(pageSzLog2));
+
+ ASSERT(!ipDirCache);
+
+#ifdef USE_DP_DIR_CACHE
+
+ //=========================== create Demand Paging type of the directory cache
+
+ // initialize cache memory manager as all file systems have mounted by now
+ if(CCacheMemoryManagerFactory::CacheMemoryManager())
+ {
+ // Note: the configuration data of min and max cache size are aligned with the memory size it
+ // occupies in kernel as we are using demand paging subsystem for dynamic cache size support.
+ // Therefore, they are refered as 'Mem Size' in following calculation.
+ // However, 'Data Size' refers to the logical size of a page, i.e. the actual data size each page
+ // contains.
+ // The constraints we have to consider when setting up the dynamic cache:
+ // 1. each page's data size is aligned with cluster size, unless cluster size is bigger than
+ // the default maximum page size allowed (typically 32 KB).
+ // 2. if page's data size is smaller than segment size (typically 4 KB), i.e. the unit size of
+ // demand paging subsystem's page management, we will still use up the whole segment for
+ // that page.
+ // 3. the default min and max cache's memory size is pre-defined in fat_config.cpp file.
+ // (see KDef_DynamicDirCacheMin & KDef_DynamicDirCacheMax).
+
+ // calculate page data size (logical view of page size)
+ const TUint32 DefMaxCachePageLog2 = iFatMount->FatConfig().DynamicDirCacheMaxPageSizeLog2();
+ const TUint32 PageDataSizeLog2 = clustSizeLog2 < DefMaxCachePageLog2 ? clustSizeLog2 : DefMaxCachePageLog2;
+
+ // calculate page number, based on memory size we have reserved
+ const TUint32 SegmentSizeLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2();
+ const TUint32 PageMemSizeLog2 = PageDataSizeLog2 < SegmentSizeLog2 ? SegmentSizeLog2 : PageDataSizeLog2;
+ TUint32 CacheSizeMinInPages = iFatMount->FatConfig().DynamicDirCacheSizeMin() >> PageMemSizeLog2;
+ TUint32 CacheSizeMaxInPages = iFatMount->FatConfig().DynamicDirCacheSizeMax() >> PageMemSizeLog2;
+
+ // cache memory client is connected via name
+ TBuf<0x20> clientName = _L("CACHE_MEM_CLIENT:");
+ clientName.Append('A'+iFatMount->DriveNumber());
+
+ TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, clientName));
+ if (err == KErrNone)
+ {
+ __PRINT4(_L("CDynamicDirCache::NewL(drv:%C, minPageNum:%u, maxPageNum:%u, pageDataSize:%u)\n"), 'A'+iFatMount->DriveNumber(), CacheSizeMinInPages, CacheSizeMaxInPages, 1<<PageDataSizeLog2);
+ return;
+ }
+ }
+#endif // USE_DP_DIR_CACHE
+
+ //=========================== create legacy type of the directory cache
+ ASSERT(!ipDirCache);
+
+ ipDirCache = CMediaWTCache::NewL(iDrive, numPages, pageSzLog2);
+ __PRINT3(_L("CDirCache::NewL(drive: %C, NumPages=%d, PageSize=%u)"), 'A'+iFatMount->DriveNumber(), numPages, 1<<pageSzLog2);
+
+ }
+
+//-------------------------------------------------------------------------------------
+
+/**
+ Initialises and re-initialises the object.
+*/
+void CAtaDisk::InitializeL()
+{
+ CRawDisk::InitializeL();
+
+ //-- there is a little issue here. after formatting FAT mounts's cluster size can change.
+ //-- dir. cache page size depends on the cluster size. This method doesn't change the dir. cache page size.
+ //-- At present it is done in CFatMountCB::InitializeL() that deletes this object and then reconstructs it again.
+
+ //-- invalidate directory cache here
+ ipDirCache->InvalidateCache();
+
+ TInt64 cacheBasePos;
+
+ if(iFatMount->FatType() == EFat32)
+ {
+ //-- this is FAT32, all directories including Root are files and aligned to the cluster heap boundary
+ //-- set dir. cache base position to the cluster heap boundary
+ const TUint32 offsetMask = (1 << iFatMount->ClusterSizeLog2() )-1;
+ cacheBasePos = (iFatMount->ClusterBasePosition() & offsetMask);
+ }
+ else
+ {
+ //-- this is FAT12/16. Root directory is a separate volume object and has no alignment.
+ //-- set cache base position to its beginning.
+ cacheBasePos = iFatMount->StartOfRootDirInBytes();
+ }
+
+ ipDirCache->SetCacheBasePos(cacheBasePos);
+
+}
+
+//-------------------------------------------------------------------------------------
+
+/**
+ Read data from the media through LRU data cache cache.
+
+ @param aPos absolute media position
+ @param aLength how many bytes to read
+ @param aDes data descriptor
+
+ @leave on error
+*/
+void CAtaDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
+ {
+ __PRINT3(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aLength);
+ iUidCache->ReadL(aPos, aLength, aDes);
+ }
+
+//-------------------------------------------------------------------------------------
+
+/**
+ Write data to the media through LRU data cache
+
+ @param aPos absolute media position
+ @param aDes data descriptor
+
+ @leave on error
+*/
+void CAtaDisk::WriteCachedL(TInt64 aPos, const TDesC8& aDes)
+ {
+ __PRINT3(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aDes.Size());
+ iUidCache->WriteL(aPos, aDes);
+ }
+
+
+//-------------------------------------------------------------------------------------
+
+/**
+ Read data from the media directly without any caches.
+ Mostly used by file IO
+
+ @param aPos absolute media position
+ @param aLength how many bytes to read
+ @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8)
+ @param aMessage Refrence to server message from request
+ @param anOffset Offset into read data to write
+
+ @leave on error
+*/
+void CAtaDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2 &aMessage,TInt anOffset) const
+ {
+
+ __PRINT4(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
+ User::LeaveIfError(iDrive.ReadNonCritical(aPos,aLength,aTrg,aMessage,anOffset));
+ }
+
+//-------------------------------------------------------------------------------------
+
+/**
+ Write data to the media directly without any cached.
+ Mostly used by file IO
+
+ This method shall invalidate some data caches to keep them in synch with the media.
+
+ @param aPos Media position in bytes
+ @param aLength Length in bytes of write
+ @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8)
+ @param aMessage Refrence to server message from request, contains data
+ @param anOffset Offset into write data to use in write
+
+ @leave on error
+*/
+void CAtaDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2 &aMessage,TInt anOffset)
+ {
+ __PRINT4(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
+
+ //-- write data to the media directly
+ User::LeaveIfError(iDrive.WriteNonCritical(aPos,aLength,aSrc,aMessage,anOffset));
+
+ //-- we need to invalidate UID cache page that corresponds to aPos (if any). This is UID caching specific. UID is stored in the first few bytes of
+ //-- the executable module and therefore belongs to one cache page only.
+ //-- If someone writes to the beginning of the exe module file, corresponding UID cache page will be invalidated and re-read from the media later
+ iUidCache->InvalidateCachePage(aPos);
+
+ //-- invalidate affected(if any) part of the FAT cache in the case if someone used to write data to FAT area, which usually do not happen
+ iFatMount->FAT().InvalidateCacheL(aPos,aLength);
+
+ }
+
+//-------------------------------------------------------------------------------------
+
+/** Get information for last disk error */
+TInt CAtaDisk::GetLastErrorInfo(TDes8& aErrorInfo) const
+ {
+ return iDrive.GetLastErrorInfo(aErrorInfo);
+ }
+
+
+//-------------------------------------------------------------------------------------
+/** Invalidate whole UID cache */
+void CAtaDisk::InvalidateUidCache()
+{
+ ASSERT(iUidCache);
+ iUidCache->InvalidateCache();
+}
+
+/**
+ Invalidate the UID cache page that has aPos cached.
+ This method doesn't pay attention to the length of the block being invalidated because
+ UID lives in the very beginning of the exe module and always fits into a single page
+*/
+void CAtaDisk::InvalidateUidCachePage(TUint64 aPos)
+{
+ ASSERT(iUidCache);
+ iUidCache->InvalidateCachePage(aPos);
+}
+
+
+//################################################################################################################################
+//## CRamDisk class implementation
+//################################################################################################################################
+
+
+/**
+ CRamDisk factory method.
+
+ @param aFatMount reference to the owner.
+ @return pointer to the constructed object.
+*/
+CRamDisk* CRamDisk::NewL(CFatMountCB& aFatMount)
+ {
+ __PRINT1(_L("CRamDisk::NewL() drv:%d"), aFatMount.DriveNumber());
+ CRamDisk* pSelf = new(ELeave)CRamDisk(aFatMount);
+
+ CleanupStack::PushL(pSelf);
+
+ pSelf->InitializeL();
+
+ CleanupStack::Pop();
+
+ return pSelf;
+ }
+
+CRamDisk::CRamDisk(CFatMountCB& aFatMount)
+ :CRawDisk(aFatMount)
+ {
+ }
+
+//-------------------------------------------------------------------------------------
+
+/**
+ Initialises and re-initialises the object.
+*/
+void CRamDisk::InitializeL()
+{
+ CRawDisk::InitializeL();
+
+ //-- set the RAM disk base
+ TLocalDriveCapsV2 caps;
+ TPckg<TLocalDriveCapsV2> capsPckg(caps);
+ User::LeaveIfError(iFatMount->LocalDrive()->Caps(capsPckg));
+
+ ASSERT(caps.iMediaAtt & KMediaAttVariableSize);
+
+ //-- set RAM disk base
+ iRamDiskBase = caps.iBaseAddress;
+ ASSERT(iRamDiskBase);
+}
+
+
+
+/** @return the start address of the Ram Drive in low memory */
+TUint8* CRamDisk::RamDiskBase() const
+ {
+ return iRamDiskBase;
+ }
+
+//-------------------------------------------------------------------------------------
+//
+// Read aLength of data from the disk
+//
+void CRamDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
+ {
+
+ __PRINT3(_L("CRamDisk::ReadL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),I64LOW(aPos),aLength);
+ __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt));
+ Mem::Copy((TUint8*)aDes.Ptr(),RamDiskBase()+I64LOW(aPos),aLength);
+ aDes.SetLength(aLength);
+ }
+
+//-------------------------------------------------------------------------------------
+//
+// Write aLength of data to the disk
+//
+void CRamDisk::WriteCachedL(TInt64 aPos,const TDesC8& aDes)
+ {
+
+ __PRINT3(_L("CRamDisk::WriteL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),aPos,aDes.Length());
+ __ASSERT_ALWAYS(aPos+aDes.Length()<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt));
+ Mem::Copy(RamDiskBase()+I64LOW(aPos),(TUint8*)aDes.Ptr(),aDes.Length());
+ }
+
+
+//-------------------------------------------------------------------------------------
+//
+// Read from ramDrive into thread relative descriptor
+//
+void CRamDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* /*aTrg*/,const RMessagePtr2 &aMessage,TInt anOffset) const
+ {
+ __PRINT2(_L("CRamDisk::ReadL TAny* Pos 0x%x, Len %d"),aPos,aLength);
+ __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt));
+ TUint8* pos=RamDiskBase()+I64LOW(aPos);
+ TPtrC8 buf(pos,aLength);
+ aMessage.WriteL(0,buf,anOffset);
+ }
+
+//-------------------------------------------------------------------------------------
+//
+// Write from thread relative descriptor into ramDrive
+//
+void CRamDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* /*aSrc*/,const RMessagePtr2 &aMessage,TInt anOffset)
+ {
+ __PRINT2(_L("CRamDisk::WriteL TAny* Pos 0x%x, Len %d"),aPos,aLength);
+ __ASSERT_ALWAYS(aPos+aLength<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt));
+ TUint8* pos=RamDiskBase()+I64LOW(aPos);
+ TPtr8 buf(pos,aLength);
+ aMessage.ReadL(0,buf,anOffset);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+