os/kernelhwsrv/userlibandfileserver/fileserver/sfat/sl_disk.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32\sfat\sl_disk.cpp
    15 // 
    16 //
    17 
    18 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    19 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    20 //!!
    21 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
    22 //!!
    23 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    24 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    25 
    26 #include "sl_disk.h"
    27 #include "sl_cache.h"
    28 #include "sl_dir_cache.h"
    29 
    30 /**
    31 @file
    32 */
    33 
    34 
    35 //################################################################################################################################
    36 //#     CRawDisk implementation
    37 //################################################################################################################################
    38 
    39 
    40 /**
    41     Factory function. Constructs objects of the classes derived from CRawDisk.
    42     
    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.
    46 */
    47 CRawDisk* CRawDisk::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps)
    48 {
    49     __PRINT1(_L("CRawDisk::NewL() drv:%d"), aOwner.DriveNumber());
    50 
    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)
    55         {
    56             ASSERT(0);
    57             return NULL;
    58         }
    59 
    60         return CRamDisk::NewL(aOwner);
    61     }
    62 
    63     //-- create CAtaDisk by default
    64     return CAtaDisk::NewL(aOwner);
    65 }
    66 
    67 
    68 CRawDisk::CRawDisk(CFatMountCB& aOwner)
    69     {
    70     iFatMount = &aOwner;
    71     }
    72 
    73 /**
    74     Default implementation. Initialises and re-initialises the object.
    75 */
    76 void CRawDisk::InitializeL()
    77     {
    78     ASSERT(iFatMount);
    79     }
    80 
    81 
    82 TInt CRawDisk::GetLastErrorInfo(TDes8& /*aErrorInfo*/) const
    83     {
    84     return KErrNotSupported;
    85     }
    86 
    87 //################################################################################################################################
    88 //##    CAtaDisk class implementation
    89 //################################################################################################################################
    90 
    91 CAtaDisk::CAtaDisk(CFatMountCB& aFatMount)
    92          :CRawDisk(aFatMount), iDrive(aFatMount.DriveInterface())
    93     {
    94     }
    95 
    96 CAtaDisk::~CAtaDisk()
    97     {
    98     delete ipDirCache;
    99     delete iUidCache;
   100     
   101     }
   102 
   103 
   104 //-------------------------------------------------------------------------------------
   105 
   106 /**
   107     CAtaDisk factory method.
   108     
   109     @param  aFatMount reference to the owner.
   110     @return pointer to the constructed object.
   111 */
   112 CAtaDisk* CAtaDisk::NewL(CFatMountCB& aFatMount)
   113     {
   114     __PRINT1(_L("CAtaDisk::NewL() drv:%d"), aFatMount.DriveNumber());
   115 
   116     CAtaDisk* pSelf = new (ELeave) CAtaDisk(aFatMount);
   117     
   118     CleanupStack::PushL(pSelf);
   119     
   120     pSelf->ConstructL();
   121     pSelf->InitializeL();
   122     
   123     CleanupStack::Pop();
   124 
   125     return pSelf;
   126     }
   127 
   128 //-------------------------------------------------------------------------------------
   129 
   130 /** 2nd stage constructor */
   131 void CAtaDisk::ConstructL()
   132     {
   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 
   136 
   137     iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2);
   138 
   139 
   140     //=========================== create directory cache
   141     
   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.
   145 
   146     __PRINT2(_L("CAtaDisk::ConstructL() Dir Cache config:%d,%d"),KDirCacheSize,KMaxDirCachePageSzLog2);
   147 
   148     ASSERT(KDirCacheSize >= K1KiloByte && KDirCacheSize <= K1MegaByte);
   149     ASSERT((KMaxDirCachePageSzLog2 >= KDefSectorSzLog2) && (Pow2(KMaxDirCachePageSzLog2) <= KDirCacheSize));
   150 
   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));
   158 
   159     ASSERT(!ipDirCache);
   160 
   161 #ifdef USE_DP_DIR_CACHE
   162 
   163     //=========================== create Demand Paging type of the directory cache
   164 
   165     // initialize cache memory manager as all file systems have mounted by now
   166     if(CCacheMemoryManagerFactory::CacheMemoryManager())
   167         {
   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
   172         //  contains.
   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
   178         //      that page.
   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).
   181 
   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;
   185         
   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;
   191 
   192         // cache memory client is connected via name 
   193         TBuf<0x20> clientName = _L("CACHE_MEM_CLIENT:");
   194         clientName.Append('A'+iFatMount->DriveNumber());
   195 
   196         TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, clientName));
   197         if (err == KErrNone)
   198             {
   199             __PRINT4(_L("CDynamicDirCache::NewL(drv:%C, minPageNum:%u, maxPageNum:%u, pageDataSize:%u)\n"), 'A'+iFatMount->DriveNumber(), CacheSizeMinInPages, CacheSizeMaxInPages, 1<<PageDataSizeLog2);
   200             return;
   201             }
   202         }
   203 #endif // USE_DP_DIR_CACHE
   204 
   205     //=========================== create legacy type of the directory cache
   206     ASSERT(!ipDirCache);
   207 
   208     ipDirCache = CMediaWTCache::NewL(iDrive, numPages, pageSzLog2);
   209     __PRINT3(_L("CDirCache::NewL(drive: %C, NumPages=%d, PageSize=%u)"), 'A'+iFatMount->DriveNumber(), numPages, 1<<pageSzLog2);
   210     
   211     }
   212 
   213 //-------------------------------------------------------------------------------------
   214 
   215 /**
   216     Initialises and re-initialises the object.
   217 */
   218 void CAtaDisk::InitializeL()
   219 {
   220     CRawDisk::InitializeL();
   221     
   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.
   225 
   226     //-- invalidate directory cache here
   227     ipDirCache->InvalidateCache();
   228     
   229     TInt64  cacheBasePos;
   230     
   231     if(iFatMount->FatType() == EFat32)
   232         {
   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);
   237         }
   238     else
   239         {
   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();
   243         }
   244 
   245     ipDirCache->SetCacheBasePos(cacheBasePos);
   246     
   247 }
   248 
   249 //-------------------------------------------------------------------------------------
   250 
   251 /**
   252     Read data from the media through LRU data cache cache. 
   253 
   254     @param  aPos        absolute media position
   255     @param  aLength     how many bytes to read
   256     @param  aDes        data descriptor
   257 
   258     @leave on error
   259 */
   260 void CAtaDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
   261     {
   262     __PRINT3(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aLength);
   263     iUidCache->ReadL(aPos, aLength, aDes);
   264     }
   265 
   266 //-------------------------------------------------------------------------------------
   267 
   268 /**
   269     Write data to the media through LRU data cache
   270 
   271     @param  aPos        absolute media position
   272     @param  aDes        data descriptor
   273 
   274     @leave on error
   275 */
   276 void CAtaDisk::WriteCachedL(TInt64 aPos, const TDesC8& aDes)
   277     {
   278     __PRINT3(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aDes.Size());
   279     iUidCache->WriteL(aPos, aDes);
   280     }
   281 
   282 
   283 //-------------------------------------------------------------------------------------
   284 
   285 /**
   286     Read data from the media directly without any caches.
   287     Mostly used by file IO
   288 
   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
   294 
   295     @leave on error
   296 */
   297 void CAtaDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2 &aMessage,TInt anOffset) const
   298     {
   299 
   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));
   302     }
   303 
   304 //-------------------------------------------------------------------------------------
   305 
   306 /**
   307     Write data to the media directly without any cached.
   308     Mostly used by file IO
   309 
   310     This method shall invalidate some data caches to keep them in synch with the media.
   311 
   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
   317 
   318     @leave on error
   319 */
   320 void CAtaDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2 &aMessage,TInt anOffset)
   321     {
   322     __PRINT4(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset);
   323 
   324     //-- write data to the media directly
   325     User::LeaveIfError(iDrive.WriteNonCritical(aPos,aLength,aSrc,aMessage,anOffset));
   326 
   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); 
   331 
   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);
   334 
   335     }
   336 
   337 //-------------------------------------------------------------------------------------
   338 
   339 /** Get information for last disk error */
   340 TInt CAtaDisk::GetLastErrorInfo(TDes8& aErrorInfo) const
   341     {
   342     return iDrive.GetLastErrorInfo(aErrorInfo);
   343     }
   344 
   345 
   346 //-------------------------------------------------------------------------------------
   347 /** Invalidate whole UID cache */
   348 void CAtaDisk::InvalidateUidCache()
   349 {
   350     ASSERT(iUidCache);
   351     iUidCache->InvalidateCache();
   352 }
   353 
   354 /** 
   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
   358 */
   359 void CAtaDisk::InvalidateUidCachePage(TUint64 aPos)
   360 {
   361     ASSERT(iUidCache);
   362     iUidCache->InvalidateCachePage(aPos);
   363 }
   364 
   365 
   366 //################################################################################################################################
   367 //##    CRamDisk class implementation
   368 //################################################################################################################################
   369 
   370 
   371 /**
   372     CRamDisk factory method.
   373     
   374     @param  aFatMount reference to the owner.
   375     @return pointer to the constructed object.
   376 */
   377 CRamDisk* CRamDisk::NewL(CFatMountCB& aFatMount)
   378     {
   379     __PRINT1(_L("CRamDisk::NewL() drv:%d"), aFatMount.DriveNumber());
   380     CRamDisk* pSelf = new(ELeave)CRamDisk(aFatMount);
   381 
   382     CleanupStack::PushL(pSelf);
   383   
   384     pSelf->InitializeL();
   385     
   386     CleanupStack::Pop();
   387 
   388     return pSelf;
   389     }
   390 
   391 CRamDisk::CRamDisk(CFatMountCB& aFatMount)
   392          :CRawDisk(aFatMount)
   393     {
   394     }
   395 
   396 //-------------------------------------------------------------------------------------
   397 
   398 /**
   399     Initialises and re-initialises the object.
   400 */
   401 void CRamDisk::InitializeL()
   402 {
   403     CRawDisk::InitializeL();
   404 
   405     //-- set the RAM disk base
   406     TLocalDriveCapsV2 caps;
   407     TPckg<TLocalDriveCapsV2> capsPckg(caps);
   408     User::LeaveIfError(iFatMount->LocalDrive()->Caps(capsPckg));
   409   
   410     ASSERT(caps.iMediaAtt & KMediaAttVariableSize);
   411     
   412     //-- set RAM disk base
   413     iRamDiskBase = caps.iBaseAddress; 
   414     ASSERT(iRamDiskBase);
   415 }
   416 
   417 
   418 
   419 /** @return the start address of the Ram Drive in low memory */
   420 TUint8* CRamDisk::RamDiskBase() const
   421     {
   422     return iRamDiskBase;
   423     }
   424 
   425 //-------------------------------------------------------------------------------------
   426 //
   427 // Read aLength of data from the disk
   428 //
   429 void CRamDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const
   430     {
   431     
   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);
   436     }
   437 
   438 //-------------------------------------------------------------------------------------
   439 //
   440 // Write aLength of data to the disk
   441 //
   442 void CRamDisk::WriteCachedL(TInt64 aPos,const TDesC8& aDes)
   443     {
   444 
   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());
   448     }
   449     
   450 
   451 //-------------------------------------------------------------------------------------
   452 //
   453 // Read from ramDrive into thread relative descriptor
   454 //
   455 void CRamDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* /*aTrg*/,const RMessagePtr2 &aMessage,TInt anOffset) const
   456     {
   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);
   462     }
   463 
   464 //-------------------------------------------------------------------------------------
   465 //
   466 // Write from thread relative descriptor into ramDrive
   467 //
   468 void CRamDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* /*aSrc*/,const RMessagePtr2 &aMessage,TInt anOffset)
   469     {
   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);
   475     }
   476 
   477 
   478 
   479 
   480 
   481 
   482 
   483 
   484 
   485 
   486 
   487 
   488 
   489 
   490 
   491 
   492 
   493 
   494 
   495 
   496 
   497 
   498 
   499 
   500 
   501 
   502