Update contrib.
1 // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfat\sl_disk.cpp
20 #include "sl_dir_cache.h"
27 //################################################################################################################################
28 //# CRawDisk implementation
29 //################################################################################################################################
33 Factory function. Constructs objects of the classes derived from CRawDisk.
35 @param aOwner reference to the onwning FAT Mount class
36 @param aLocDrvCaps local drive capabilities from the media driver
37 @return pointer to the constructed object. May be NULL on error.
39 CRawDisk* CRawDisk::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps)
41 __PRINT1(_L("CRawDisk::NewL() drv:%d"), aOwner.DriveNumber());
43 if(aLocDrvCaps.iMediaAtt & KMediaAttVariableSize)
44 {//-- this is the RAM drive "attribute"
45 ASSERT((aLocDrvCaps.iDriveAtt & (KDriveAttInternal|KDriveAttLocal)) && aLocDrvCaps.iType == EMediaRam);
46 if(!aLocDrvCaps.iBaseAddress)
52 return CRamDisk::NewL(aOwner);
55 //-- create CAtaDisk by default
56 return CAtaDisk::NewL(aOwner);
60 CRawDisk::CRawDisk(CFatMountCB& aOwner)
66 Default implementation. Initialises and re-initialises the object.
68 void CRawDisk::InitializeL()
74 TInt CRawDisk::GetLastErrorInfo(TDes8& /*aErrorInfo*/) const
76 return KErrNotSupported;
79 //################################################################################################################################
80 //## CAtaDisk class implementation
81 //################################################################################################################################
83 CAtaDisk::CAtaDisk(CFatMountCB& aFatMount)
84 :CRawDisk(aFatMount), iDrive(aFatMount.DriveInterface())
96 //-------------------------------------------------------------------------------------
99 CAtaDisk factory method.
101 @param aFatMount reference to the owner.
102 @return pointer to the constructed object.
104 CAtaDisk* CAtaDisk::NewL(CFatMountCB& aFatMount)
106 __PRINT1(_L("CAtaDisk::NewL() drv:%d"), aFatMount.DriveNumber());
108 CAtaDisk* pSelf = new (ELeave) CAtaDisk(aFatMount);
110 CleanupStack::PushL(pSelf);
113 pSelf->InitializeL();
120 //-------------------------------------------------------------------------------------
122 /** 2nd stage constructor */
123 void CAtaDisk::ConstructL()
125 //=========================== create data WT cache that is primarily used for caching exacutable modules' UIDs
126 const TUint32 KUidCachePageSzLog2 = 9; //-- 512 bytes in page
127 const TUint32 KUidCachePages = 64; //-- 64 pages; total cache size is 32K
129 iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2);
132 //=========================== create directory cache
134 //-- Get dir. cache parameters from config. They may be set in estart.txt for a specified drive.
135 const TUint32 KDirCacheSize = iFatMount->FatConfig().DirCacheSize(); //- Total directory cache size, bytes.
136 const TUint32 KMaxDirCachePageSzLog2 = iFatMount->FatConfig().DirCacheMaxPageSizeLog2(); //- Log2 of the Max. dir. cache page.
138 __PRINT2(_L("CAtaDisk::ConstructL() Dir Cache config:%d,%d"),KDirCacheSize,KMaxDirCachePageSzLog2);
140 ASSERT(KDirCacheSize >= K1KiloByte && KDirCacheSize <= K1MegaByte);
141 ASSERT((KMaxDirCachePageSzLog2 >= KDefSectorSzLog2) && (Pow2(KMaxDirCachePageSzLog2) <= KDirCacheSize));
143 //-- calculate the size and number of pages for the dir. cache.
144 //-- if the mount's cluster size is less than max. page size from config, the page size will be cluster size.
145 //-- 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.
146 //-- The number of pages depends on total cache size and page size.
147 const TUint clustSizeLog2 = iFatMount->ClusterSizeLog2(); //-- current FAT cluster size Log2
148 const TUint32 pageSzLog2 = (clustSizeLog2 <= KMaxDirCachePageSzLog2) ? clustSizeLog2 : KMaxDirCachePageSzLog2;
149 const TUint32 numPages = KDirCacheSize / (Pow2(pageSzLog2));
153 #ifdef USE_DP_DIR_CACHE
155 //=========================== create Demand Paging type of the directory cache
157 // initialize cache memory manager as all file systems have mounted by now
158 if(CCacheMemoryManagerFactory::CacheMemoryManager())
160 // Note: the configuration data of min and max cache size are aligned with the memory size it
161 // occupies in kernel as we are using demand paging subsystem for dynamic cache size support.
162 // Therefore, they are refered as 'Mem Size' in following calculation.
163 // However, 'Data Size' refers to the logical size of a page, i.e. the actual data size each page
165 // The constraints we have to consider when setting up the dynamic cache:
166 // 1. each page's data size is aligned with cluster size, unless cluster size is bigger than
167 // the default maximum page size allowed (typically 32 KB).
168 // 2. if page's data size is smaller than segment size (typically 4 KB), i.e. the unit size of
169 // demand paging subsystem's page management, we will still use up the whole segment for
171 // 3. the default min and max cache's memory size is pre-defined in fat_config.cpp file.
172 // (see KDef_DynamicDirCacheMin & KDef_DynamicDirCacheMax).
174 // calculate page data size (logical view of page size)
175 const TUint32 DefMaxCachePageLog2 = iFatMount->FatConfig().DynamicDirCacheMaxPageSizeLog2();
176 const TUint32 PageDataSizeLog2 = clustSizeLog2 < DefMaxCachePageLog2 ? clustSizeLog2 : DefMaxCachePageLog2;
178 // calculate page number, based on memory size we have reserved
179 const TUint32 SegmentSizeLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2();
180 const TUint32 PageMemSizeLog2 = PageDataSizeLog2 < SegmentSizeLog2 ? SegmentSizeLog2 : PageDataSizeLog2;
181 TUint32 CacheSizeMinInPages = iFatMount->FatConfig().DynamicDirCacheSizeMin() >> PageMemSizeLog2;
182 TUint32 CacheSizeMaxInPages = iFatMount->FatConfig().DynamicDirCacheSizeMax() >> PageMemSizeLog2;
184 // cache memory client is connected via name
185 TBuf<0x20> clientName = _L("CACHE_MEM_CLIENT:");
186 clientName.Append('A'+iFatMount->DriveNumber());
188 TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, clientName));
192 //-- fall back to constructing old type of cache
195 #endif // USE_DP_DIR_CACHE
197 //=========================== create legacy type of the directory cache
200 ipDirCache = CMediaWTCache::NewL(iDrive, numPages, pageSzLog2);
201 __PRINT3(_L("CDirCache::NewL(drive: %C, NumPages=%d, PageSize=%u)"), 'A'+iFatMount->DriveNumber(), numPages, 1<<pageSzLog2);
205 //-------------------------------------------------------------------------------------
208 Initialises and re-initialises the object.
210 void CAtaDisk::InitializeL()
212 CRawDisk::InitializeL();
214 //-- there is a little issue here. after formatting FAT mounts's cluster size can change.
215 //-- dir. cache page size depends on the cluster size. This method doesn't change the dir. cache page size.
216 //-- At present it is done in CFatMountCB::InitializeL() that deletes this object and then reconstructs it again.
218 //-- invalidate directory cache here
219 ipDirCache->InvalidateCache();
223 if(iFatMount->FatType() == EFat32)
225 //-- this is FAT32, all directories including Root are files and aligned to the cluster heap boundary
226 //-- set dir. cache base position to the cluster heap boundary
227 const TUint32 offsetMask = (1 << iFatMount->ClusterSizeLog2() )-1;
228 cacheBasePos = (iFatMount->ClusterBasePosition() & offsetMask);
232 //-- this is FAT12/16. Root directory is a separate volume object and has no alignment.
233 //-- set cache base position to its beginning.
234 cacheBasePos = iFatMount->StartOfRootDirInBytes();
237 ipDirCache->SetCacheBasePos(cacheBasePos);
241 //-------------------------------------------------------------------------------------
244 Read data from the media through LRU data cache cache.
246 @param aPos absolute media position
247 @param aLength how many bytes to read
248 @param aDes data descriptor
252 void CAtaDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
254 __PRINT3(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aLength);
255 iUidCache->ReadL(aPos, aLength, aDes);
258 //-------------------------------------------------------------------------------------
261 Write data to the media through LRU data cache
263 @param aPos absolute media position
264 @param aDes data descriptor
268 void CAtaDisk::WriteCachedL(TInt64 aPos, const TDesC8& aDes)
270 __PRINT3(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aDes.Size());
271 iUidCache->WriteL(aPos, aDes);
275 //-------------------------------------------------------------------------------------
278 Read data from the media directly without any caches.
279 Mostly used by file IO
281 @param aPos absolute media position
282 @param aLength how many bytes to read
283 @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8)
284 @param aMessage Refrence to server message from request
285 @param anOffset Offset into read data to write
289 void CAtaDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2 &aMessage,TInt anOffset) const
292 __PRINT4(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
293 User::LeaveIfError(iDrive.ReadNonCritical(aPos,aLength,aTrg,aMessage,anOffset));
296 //-------------------------------------------------------------------------------------
299 Write data to the media directly without any cached.
300 Mostly used by file IO
302 This method shall invalidate some data caches to keep them in synch with the media.
304 @param aPos Media position in bytes
305 @param aLength Length in bytes of write
306 @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8)
307 @param aMessage Refrence to server message from request, contains data
308 @param anOffset Offset into write data to use in write
312 void CAtaDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2 &aMessage,TInt anOffset)
314 __PRINT4(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
316 //-- write data to the media directly
317 User::LeaveIfError(iDrive.WriteNonCritical(aPos,aLength,aSrc,aMessage,anOffset));
319 //-- 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
320 //-- the executable module and therefore belongs to one cache page only.
321 //-- 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
322 iUidCache->InvalidateCachePage(aPos);
324 //-- 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
325 iFatMount->FAT().InvalidateCacheL(aPos,aLength);
329 //-------------------------------------------------------------------------------------
331 /** Get information for last disk error */
332 TInt CAtaDisk::GetLastErrorInfo(TDes8& aErrorInfo) const
334 return iDrive.GetLastErrorInfo(aErrorInfo);
338 //-------------------------------------------------------------------------------------
339 /** Invalidate whole UID cache */
340 void CAtaDisk::InvalidateUidCache()
343 iUidCache->InvalidateCache();
347 Invalidate the UID cache page that has aPos cached.
348 This method doesn't pay attention to the length of the block being invalidated because
349 UID lives in the very beginning of the exe module and always fits into a single page
351 void CAtaDisk::InvalidateUidCachePage(TUint64 aPos)
354 iUidCache->InvalidateCachePage(aPos);
358 //################################################################################################################################
359 //## CRamDisk class implementation
360 //################################################################################################################################
364 CRamDisk factory method.
366 @param aFatMount reference to the owner.
367 @return pointer to the constructed object.
369 CRamDisk* CRamDisk::NewL(CFatMountCB& aFatMount)
371 __PRINT1(_L("CRamDisk::NewL() drv:%d"), aFatMount.DriveNumber());
372 CRamDisk* pSelf = new(ELeave)CRamDisk(aFatMount);
374 CleanupStack::PushL(pSelf);
376 pSelf->InitializeL();
383 CRamDisk::CRamDisk(CFatMountCB& aFatMount)
388 //-------------------------------------------------------------------------------------
391 Initialises and re-initialises the object.
393 void CRamDisk::InitializeL()
395 CRawDisk::InitializeL();
397 //-- set the RAM disk base
398 TLocalDriveCapsV2 caps;
399 TPckg<TLocalDriveCapsV2> capsPckg(caps);
400 User::LeaveIfError(iFatMount->LocalDrive()->Caps(capsPckg));
402 ASSERT(caps.iMediaAtt & KMediaAttVariableSize);
404 //-- set RAM disk base
405 iRamDiskBase = caps.iBaseAddress;
406 ASSERT(iRamDiskBase);
411 /** @return the start address of the Ram Drive in low memory */
412 TUint8* CRamDisk::RamDiskBase() const
417 //-------------------------------------------------------------------------------------
419 // Read aLength of data from the disk
421 void CRamDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
424 __PRINT3(_L("CRamDisk::ReadL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),I64LOW(aPos),aLength);
425 __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt));
426 Mem::Copy((TUint8*)aDes.Ptr(),RamDiskBase()+I64LOW(aPos),aLength);
427 aDes.SetLength(aLength);
430 //-------------------------------------------------------------------------------------
432 // Write aLength of data to the disk
434 void CRamDisk::WriteCachedL(TInt64 aPos,const TDesC8& aDes)
437 __PRINT3(_L("CRamDisk::WriteL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),aPos,aDes.Length());
438 __ASSERT_ALWAYS(aPos+aDes.Length()<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt));
439 Mem::Copy(RamDiskBase()+I64LOW(aPos),(TUint8*)aDes.Ptr(),aDes.Length());
443 //-------------------------------------------------------------------------------------
445 // Read from ramDrive into thread relative descriptor
447 void CRamDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* /*aTrg*/,const RMessagePtr2 &aMessage,TInt anOffset) const
449 __PRINT2(_L("CRamDisk::ReadL TAny* Pos 0x%x, Len %d"),aPos,aLength);
450 __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt));
451 TUint8* pos=RamDiskBase()+I64LOW(aPos);
452 TPtrC8 buf(pos,aLength);
453 aMessage.WriteL(0,buf,anOffset);
456 //-------------------------------------------------------------------------------------
458 // Write from thread relative descriptor into ramDrive
460 void CRamDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* /*aSrc*/,const RMessagePtr2 &aMessage,TInt anOffset)
462 __PRINT2(_L("CRamDisk::WriteL TAny* Pos 0x%x, Len %d"),aPos,aLength);
463 __ASSERT_ALWAYS(aPos+aLength<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt));
464 TUint8* pos=RamDiskBase()+I64LOW(aPos);
465 TPtr8 buf(pos,aLength);
466 aMessage.ReadL(0,buf,anOffset);