First public contribution.
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
18 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
19 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
23 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
24 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
28 #include "sl_dir_cache.h"
35 //################################################################################################################################
36 //# CRawDisk implementation
37 //################################################################################################################################
41 Factory function. Constructs objects of the classes derived from CRawDisk.
43 @param aOwner reference to the onwning FAT Mount class
44 @param aLocDrvCaps local drive capabilities from the media driver
45 @return pointer to the constructed object. May be NULL on error.
47 CRawDisk* CRawDisk::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps)
49 __PRINT1(_L("CRawDisk::NewL() drv:%d"), aOwner.DriveNumber());
51 if(aLocDrvCaps.iMediaAtt & KMediaAttVariableSize)
52 {//-- this is the RAM drive "attribute"
53 ASSERT((aLocDrvCaps.iDriveAtt & (KDriveAttInternal|KDriveAttLocal)) && aLocDrvCaps.iType == EMediaRam);
54 if(!aLocDrvCaps.iBaseAddress)
60 return CRamDisk::NewL(aOwner);
63 //-- create CAtaDisk by default
64 return CAtaDisk::NewL(aOwner);
68 CRawDisk::CRawDisk(CFatMountCB& aOwner)
74 Default implementation. Initialises and re-initialises the object.
76 void CRawDisk::InitializeL()
82 TInt CRawDisk::GetLastErrorInfo(TDes8& /*aErrorInfo*/) const
84 return KErrNotSupported;
87 //################################################################################################################################
88 //## CAtaDisk class implementation
89 //################################################################################################################################
91 CAtaDisk::CAtaDisk(CFatMountCB& aFatMount)
92 :CRawDisk(aFatMount), iDrive(aFatMount.DriveInterface())
104 //-------------------------------------------------------------------------------------
107 CAtaDisk factory method.
109 @param aFatMount reference to the owner.
110 @return pointer to the constructed object.
112 CAtaDisk* CAtaDisk::NewL(CFatMountCB& aFatMount)
114 __PRINT1(_L("CAtaDisk::NewL() drv:%d"), aFatMount.DriveNumber());
116 CAtaDisk* pSelf = new (ELeave) CAtaDisk(aFatMount);
118 CleanupStack::PushL(pSelf);
121 pSelf->InitializeL();
128 //-------------------------------------------------------------------------------------
130 /** 2nd stage constructor */
131 void CAtaDisk::ConstructL()
133 //=========================== create data WT cache that is primarily used for caching exacutable modules' UIDs
134 const TUint32 KUidCachePageSzLog2 = 9; //-- 512 bytes in page
135 const TUint32 KUidCachePages = 64; //-- 64 pages; total cache size is 32K
137 iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2);
140 //=========================== create directory cache
142 //-- Get dir. cache parameters from config. They may be set in estart.txt for a specified drive.
143 const TUint32 KDirCacheSize = iFatMount->FatConfig().DirCacheSize(); //- Total directory cache size, bytes.
144 const TUint32 KMaxDirCachePageSzLog2 = iFatMount->FatConfig().DirCacheMaxPageSizeLog2(); //- Log2 of the Max. dir. cache page.
146 __PRINT2(_L("CAtaDisk::ConstructL() Dir Cache config:%d,%d"),KDirCacheSize,KMaxDirCachePageSzLog2);
148 ASSERT(KDirCacheSize >= K1KiloByte && KDirCacheSize <= K1MegaByte);
149 ASSERT((KMaxDirCachePageSzLog2 >= KDefSectorSzLog2) && (Pow2(KMaxDirCachePageSzLog2) <= KDirCacheSize));
151 //-- calculate the size and number of pages for the dir. cache.
152 //-- if the mount's cluster size is less than max. page size from config, the page size will be cluster size.
153 //-- 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.
154 //-- The number of pages depends on total cache size and page size.
155 const TUint clustSizeLog2 = iFatMount->ClusterSizeLog2(); //-- current FAT cluster size Log2
156 const TUint32 pageSzLog2 = (clustSizeLog2 <= KMaxDirCachePageSzLog2) ? clustSizeLog2 : KMaxDirCachePageSzLog2;
157 const TUint32 numPages = KDirCacheSize / (Pow2(pageSzLog2));
161 #ifdef USE_DP_DIR_CACHE
163 //=========================== create Demand Paging type of the directory cache
165 // initialize cache memory manager as all file systems have mounted by now
166 if(CCacheMemoryManagerFactory::CacheMemoryManager())
168 // Note: the configuration data of min and max cache size are aligned with the memory size it
169 // occupies in kernel as we are using demand paging subsystem for dynamic cache size support.
170 // Therefore, they are refered as 'Mem Size' in following calculation.
171 // However, 'Data Size' refers to the logical size of a page, i.e. the actual data size each page
173 // The constraints we have to consider when setting up the dynamic cache:
174 // 1. each page's data size is aligned with cluster size, unless cluster size is bigger than
175 // the default maximum page size allowed (typically 32 KB).
176 // 2. if page's data size is smaller than segment size (typically 4 KB), i.e. the unit size of
177 // demand paging subsystem's page management, we will still use up the whole segment for
179 // 3. the default min and max cache's memory size is pre-defined in fat_config.cpp file.
180 // (see KDef_DynamicDirCacheMin & KDef_DynamicDirCacheMax).
182 // calculate page data size (logical view of page size)
183 const TUint32 DefMaxCachePageLog2 = iFatMount->FatConfig().DynamicDirCacheMaxPageSizeLog2();
184 const TUint32 PageDataSizeLog2 = clustSizeLog2 < DefMaxCachePageLog2 ? clustSizeLog2 : DefMaxCachePageLog2;
186 // calculate page number, based on memory size we have reserved
187 const TUint32 SegmentSizeLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2();
188 const TUint32 PageMemSizeLog2 = PageDataSizeLog2 < SegmentSizeLog2 ? SegmentSizeLog2 : PageDataSizeLog2;
189 TUint32 CacheSizeMinInPages = iFatMount->FatConfig().DynamicDirCacheSizeMin() >> PageMemSizeLog2;
190 TUint32 CacheSizeMaxInPages = iFatMount->FatConfig().DynamicDirCacheSizeMax() >> PageMemSizeLog2;
192 // cache memory client is connected via name
193 TBuf<0x20> clientName = _L("CACHE_MEM_CLIENT:");
194 clientName.Append('A'+iFatMount->DriveNumber());
196 TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, clientName));
199 __PRINT4(_L("CDynamicDirCache::NewL(drv:%C, minPageNum:%u, maxPageNum:%u, pageDataSize:%u)\n"), 'A'+iFatMount->DriveNumber(), CacheSizeMinInPages, CacheSizeMaxInPages, 1<<PageDataSizeLog2);
203 #endif // USE_DP_DIR_CACHE
205 //=========================== create legacy type of the directory cache
208 ipDirCache = CMediaWTCache::NewL(iDrive, numPages, pageSzLog2);
209 __PRINT3(_L("CDirCache::NewL(drive: %C, NumPages=%d, PageSize=%u)"), 'A'+iFatMount->DriveNumber(), numPages, 1<<pageSzLog2);
213 //-------------------------------------------------------------------------------------
216 Initialises and re-initialises the object.
218 void CAtaDisk::InitializeL()
220 CRawDisk::InitializeL();
222 //-- there is a little issue here. after formatting FAT mounts's cluster size can change.
223 //-- dir. cache page size depends on the cluster size. This method doesn't change the dir. cache page size.
224 //-- At present it is done in CFatMountCB::InitializeL() that deletes this object and then reconstructs it again.
226 //-- invalidate directory cache here
227 ipDirCache->InvalidateCache();
231 if(iFatMount->FatType() == EFat32)
233 //-- this is FAT32, all directories including Root are files and aligned to the cluster heap boundary
234 //-- set dir. cache base position to the cluster heap boundary
235 const TUint32 offsetMask = (1 << iFatMount->ClusterSizeLog2() )-1;
236 cacheBasePos = (iFatMount->ClusterBasePosition() & offsetMask);
240 //-- this is FAT12/16. Root directory is a separate volume object and has no alignment.
241 //-- set cache base position to its beginning.
242 cacheBasePos = iFatMount->StartOfRootDirInBytes();
245 ipDirCache->SetCacheBasePos(cacheBasePos);
249 //-------------------------------------------------------------------------------------
252 Read data from the media through LRU data cache cache.
254 @param aPos absolute media position
255 @param aLength how many bytes to read
256 @param aDes data descriptor
260 void CAtaDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
262 __PRINT3(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aLength);
263 iUidCache->ReadL(aPos, aLength, aDes);
266 //-------------------------------------------------------------------------------------
269 Write data to the media through LRU data cache
271 @param aPos absolute media position
272 @param aDes data descriptor
276 void CAtaDisk::WriteCachedL(TInt64 aPos, const TDesC8& aDes)
278 __PRINT3(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aDes.Size());
279 iUidCache->WriteL(aPos, aDes);
283 //-------------------------------------------------------------------------------------
286 Read data from the media directly without any caches.
287 Mostly used by file IO
289 @param aPos absolute media position
290 @param aLength how many bytes to read
291 @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8)
292 @param aMessage Refrence to server message from request
293 @param anOffset Offset into read data to write
297 void CAtaDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2 &aMessage,TInt anOffset) const
300 __PRINT4(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
301 User::LeaveIfError(iDrive.ReadNonCritical(aPos,aLength,aTrg,aMessage,anOffset));
304 //-------------------------------------------------------------------------------------
307 Write data to the media directly without any cached.
308 Mostly used by file IO
310 This method shall invalidate some data caches to keep them in synch with the media.
312 @param aPos Media position in bytes
313 @param aLength Length in bytes of write
314 @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8)
315 @param aMessage Refrence to server message from request, contains data
316 @param anOffset Offset into write data to use in write
320 void CAtaDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2 &aMessage,TInt anOffset)
322 __PRINT4(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
324 //-- write data to the media directly
325 User::LeaveIfError(iDrive.WriteNonCritical(aPos,aLength,aSrc,aMessage,anOffset));
327 //-- 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
328 //-- the executable module and therefore belongs to one cache page only.
329 //-- 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
330 iUidCache->InvalidateCachePage(aPos);
332 //-- 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
333 iFatMount->FAT().InvalidateCacheL(aPos,aLength);
337 //-------------------------------------------------------------------------------------
339 /** Get information for last disk error */
340 TInt CAtaDisk::GetLastErrorInfo(TDes8& aErrorInfo) const
342 return iDrive.GetLastErrorInfo(aErrorInfo);
346 //-------------------------------------------------------------------------------------
347 /** Invalidate whole UID cache */
348 void CAtaDisk::InvalidateUidCache()
351 iUidCache->InvalidateCache();
355 Invalidate the UID cache page that has aPos cached.
356 This method doesn't pay attention to the length of the block being invalidated because
357 UID lives in the very beginning of the exe module and always fits into a single page
359 void CAtaDisk::InvalidateUidCachePage(TUint64 aPos)
362 iUidCache->InvalidateCachePage(aPos);
366 //################################################################################################################################
367 //## CRamDisk class implementation
368 //################################################################################################################################
372 CRamDisk factory method.
374 @param aFatMount reference to the owner.
375 @return pointer to the constructed object.
377 CRamDisk* CRamDisk::NewL(CFatMountCB& aFatMount)
379 __PRINT1(_L("CRamDisk::NewL() drv:%d"), aFatMount.DriveNumber());
380 CRamDisk* pSelf = new(ELeave)CRamDisk(aFatMount);
382 CleanupStack::PushL(pSelf);
384 pSelf->InitializeL();
391 CRamDisk::CRamDisk(CFatMountCB& aFatMount)
396 //-------------------------------------------------------------------------------------
399 Initialises and re-initialises the object.
401 void CRamDisk::InitializeL()
403 CRawDisk::InitializeL();
405 //-- set the RAM disk base
406 TLocalDriveCapsV2 caps;
407 TPckg<TLocalDriveCapsV2> capsPckg(caps);
408 User::LeaveIfError(iFatMount->LocalDrive()->Caps(capsPckg));
410 ASSERT(caps.iMediaAtt & KMediaAttVariableSize);
412 //-- set RAM disk base
413 iRamDiskBase = caps.iBaseAddress;
414 ASSERT(iRamDiskBase);
419 /** @return the start address of the Ram Drive in low memory */
420 TUint8* CRamDisk::RamDiskBase() const
425 //-------------------------------------------------------------------------------------
427 // Read aLength of data from the disk
429 void CRamDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
432 __PRINT3(_L("CRamDisk::ReadL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),I64LOW(aPos),aLength);
433 __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt));
434 Mem::Copy((TUint8*)aDes.Ptr(),RamDiskBase()+I64LOW(aPos),aLength);
435 aDes.SetLength(aLength);
438 //-------------------------------------------------------------------------------------
440 // Write aLength of data to the disk
442 void CRamDisk::WriteCachedL(TInt64 aPos,const TDesC8& aDes)
445 __PRINT3(_L("CRamDisk::WriteL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),aPos,aDes.Length());
446 __ASSERT_ALWAYS(aPos+aDes.Length()<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt));
447 Mem::Copy(RamDiskBase()+I64LOW(aPos),(TUint8*)aDes.Ptr(),aDes.Length());
451 //-------------------------------------------------------------------------------------
453 // Read from ramDrive into thread relative descriptor
455 void CRamDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* /*aTrg*/,const RMessagePtr2 &aMessage,TInt anOffset) const
457 __PRINT2(_L("CRamDisk::ReadL TAny* Pos 0x%x, Len %d"),aPos,aLength);
458 __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt));
459 TUint8* pos=RamDiskBase()+I64LOW(aPos);
460 TPtrC8 buf(pos,aLength);
461 aMessage.WriteL(0,buf,anOffset);
464 //-------------------------------------------------------------------------------------
466 // Write from thread relative descriptor into ramDrive
468 void CRamDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* /*aSrc*/,const RMessagePtr2 &aMessage,TInt anOffset)
470 __PRINT2(_L("CRamDisk::WriteL TAny* Pos 0x%x, Len %d"),aPos,aLength);
471 __ASSERT_ALWAYS(aPos+aLength<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt));
472 TUint8* pos=RamDiskBase()+I64LOW(aPos);
473 TPtr8 buf(pos,aLength);
474 aMessage.ReadL(0,buf,anOffset);