diff -r 2d65c2f76d7b -r 4a8fed1c0ef6 userlibandfileserver/fileserver/sfat32/sl_cache.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_cache.cpp Tue Feb 02 01:24:03 2010 +0200 +++ b/userlibandfileserver/fileserver/sfat32/sl_cache.cpp Sat Feb 20 00:10:51 2010 +0200 @@ -28,19 +28,12 @@ CWTCachePage* CWTCachePage::NewL(TUint32 aPageSizeLog2) { CWTCachePage* pSelf = new (ELeave)CWTCachePage; - pSelf->ConstructL(aPageSizeLog2); + + pSelf->iData.CreateMaxL(1 << aPageSizeLog2); return pSelf; } -/** - 2nd stage constructor. - @param aPageSizeLog2 Log2(cache page size in bytes) -*/ -void CWTCachePage::ConstructL(TUint32 aPageSizeLog2) - { - iData.CreateMaxL(1 << aPageSizeLog2); - } CWTCachePage::CWTCachePage() { @@ -82,46 +75,45 @@ @param aDrive reference to the driver for media access. @param aNumPages number of cache pages to be created - @param aPageSizeLog2 Log2 of the page size in bytes + @param aPageSizeLog2 Log2 of the page size in bytes, this is the cache read granularity + @param aWrGranularityLog2 Log2(cache write granularity) @return a pointer to the created object. */ -CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2) +CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2) { -#ifndef ENABLE_DEDICATED_DIR_CACHE - //-- dedicated directory cache isn't enabled - (void)aDrive; //-- supress compiler's warning - (void)aClusterSizeLog2; - return NULL; -#else - - //-- dedicated directory cache is enabled, create it - ASSERT(aPageSizeLog2); - ASSERT(aNumPages); CMediaWTCache* pSelf = new (ELeave) CMediaWTCache(aDrive); CleanupStack::PushL(pSelf); - pSelf->ConstructL(aNumPages, aPageSizeLog2); + pSelf->InitialiseL(aNumPages, aPageSizeLog2, aWrGranularityLog2); CleanupStack::Pop(); return pSelf; - -#endif } /** 2nd stage constructor. @param aNumPages number of pages in the directory cache. - @param aPageSizeLog2 Log2(single cache page size in bytes) + @param aPageSizeLog2 Log2 of the page size in bytes, this is the cache read granularity + @param aWrGranularityLog2 Log2(cache write granularity) */ -void CMediaWTCache::ConstructL(TUint32 aNumPages, TUint32 aPageSizeLog2) +void CMediaWTCache::InitialiseL(TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2) { ASSERT(aNumPages && aPageSizeLog2); - __PRINT2(_L("#CMediaWTCache::CreateL() Pages=%d, PageSize=%d"), aNumPages, 1<= KDefSectorSzLog2 && aWrGranularityLog2 <= aPageSizeLog2); + } iPageSizeLog2 = aPageSizeLog2; + iWrGranularityLog2 = aWrGranularityLog2; //-- create cache pages for(TUint cnt=0; cntiStartPos; - return PageSize(); } @@ -483,9 +473,35 @@ if(dataLen <= bytesToPageEnd) {//-- data section completely fits to the cache page Mem::Copy(pPage->PtrInCachePage(aPos), pData, dataLen); //-- update cache + + //-- make small write a multiple of a write granularity size (if it is used at all) + //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal + TPtrC8 desBlock(aDes); + + if(iWrGranularityLog2) + {//-- write granularity is used + const TInt64 newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the write granularity size + TUint32 newLen = (TUint32)(aPos - newPos)+dataLen; //-- round block size up to the write granularity size + newLen = RoundUp(newLen, iWrGranularityLog2); + + const TUint8* pd = pPage->PtrInCachePage(newPos); + desBlock.Set(pd, newLen); + aPos = newPos; + } + + + //-- write data to the media + const TInt nErr = iDrive.WriteCritical(aPos, desBlock); + if(nErr != KErrNone) + {//-- some serious problem occured during writing, invalidate cache. + InvalidateCache(); + User::Leave(nErr); + } + } else {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write + //-- this is a very rare case. TInt64 currMediaPos(aPos); //-- current media position @@ -523,9 +539,6 @@ Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, dataLen); } - }// else(dataLen <= bytesToPageEnd) - - //-- write data to the media const TInt nErr = iDrive.WriteCritical(aPos,aDes); if(nErr != KErrNone) @@ -534,6 +547,10 @@ User::Leave(nErr); } + }// else(dataLen <= bytesToPageEnd) + + + MakePageLRU(nPage); //-- push the page to the top of the priority list }