userlibandfileserver/fileserver/sfile/sf_file_cache.cpp
branchRCL_3
changeset 43 c1f20ce4abcf
parent 41 0ffb4e86fcc9
child 44 3e88ff8f41d5
equal deleted inserted replaced
42:a179b74831c9 43:c1f20ce4abcf
    29 #include <hal.h>
    29 #include <hal.h>
    30 #include "sf_file_cache.h"
    30 #include "sf_file_cache.h"
    31 #include "sf_cache_man.h"
    31 #include "sf_cache_man.h"
    32 #include "sf_cache_client.h"
    32 #include "sf_cache_client.h"
    33 #include "sf_file_cache_defs.h"
    33 #include "sf_file_cache_defs.h"
       
    34 
       
    35 #ifdef OST_TRACE_COMPILER_IN_USE
       
    36 #include "sf_file_cacheTraces.h"
       
    37 #endif
    34 
    38 
    35 
    39 
    36 // disables flushing of stale cachelines before each write
    40 // disables flushing of stale cachelines before each write
    37 #define LAZY_WRITE
    41 #define LAZY_WRITE
    38 
    42 
    78 	User::Panic(_L("FSFILECACHE"), aFault);
    82 	User::Panic(_L("FSFILECACHE"), aFault);
    79 	}
    83 	}
    80 
    84 
    81 const TInt KMinSequentialReadsBeforeReadAhead = 3;
    85 const TInt KMinSequentialReadsBeforeReadAhead = 3;
    82 
    86 
       
    87 #ifdef DOUBLE_BUFFERED_WRITING
       
    88 const TInt KMinSequentialAppendsBeforeFlush = 3;
       
    89 #endif
       
    90 
    83 //************************************
    91 //************************************
    84 // CFileCache
    92 // CFileCache
    85 //************************************
    93 //************************************
    86 
    94 
    87 inline TBool ReadCachingEnabled(CFileShare& aShare)
    95 inline TBool ReadCachingEnabled(CFileShare& aShare)
  1161 
  1169 
  1162 				if (currentPos > iSize64)
  1170 				if (currentPos > iSize64)
  1163 					currentPos = iSize64;
  1171 					currentPos = iSize64;
  1164 				iInitialSize = iSize64;
  1172 				iInitialSize = iSize64;
  1165 
  1173 
       
  1174 
       
  1175 #ifdef DOUBLE_BUFFERED_WRITING
       
  1176 				// count the number of sequential write-appends
       
  1177 				if (currentOperation->iClientRequest)
       
  1178 					{
       
  1179 					if (currentPos == iSize64)
       
  1180 						iSequentialAppends++;
       
  1181 					else
       
  1182 						iSequentialAppends = 0;
       
  1183 					}
       
  1184 #endif // DOUBLE_BUFFERED_WRITING
       
  1185 
  1166 				// if EFileWriteDirectIO OR 
  1186 				// if EFileWriteDirectIO OR 
  1167 				// (caching writes and requested write len > size of the cache), 
  1187 				// (caching writes and requested write len > size of the cache), 
  1168 				// flush the write cache
  1188 				// flush the write cache
  1169 				if ((aMode & EFileWriteBuffered) == 0 || 
  1189 				if ((aMode & EFileWriteBuffered) == 0 || 
  1170 					(cachingWrites && totalLen > iCacheSize))
  1190 					(cachingWrites && totalLen > iCacheSize))
  1269 					TInt r = DoFlushDirty(aNewRequest, &aMsgRequest, EFlushSingle);
  1289 					TInt r = DoFlushDirty(aNewRequest, &aMsgRequest, EFlushSingle);
  1270 					if (r != CFsRequest::EReqActionBusy && r != CFsRequest::EReqActionComplete)
  1290 					if (r != CFsRequest::EReqActionBusy && r != CFsRequest::EReqActionComplete)
  1271 						lastError = r;
  1291 						lastError = r;
  1272 					}
  1292 					}
  1273 #endif
  1293 #endif
       
  1294 #ifdef DOUBLE_BUFFERED_WRITING
       
  1295 				if (cachingWrites && lastError == KErrNone && 
       
  1296 					iSequentialAppends >= KMinSequentialAppendsBeforeFlush && iCacheClient->LockedSegmentsHalfUsed())
       
  1297 					{
       
  1298 					DoFlushDirty(aNewRequest, &aMsgRequest, EFlushHalf);
       
  1299 					}
       
  1300 #endif
  1274 				// if no cacheline found & write caching is enabled, allocate a new cacheline
  1301 				// if no cacheline found & write caching is enabled, allocate a new cacheline
  1275 				if (cachingWrites && addr == NULL && lastError == KErrNone)
  1302 				if (cachingWrites && addr == NULL && lastError == KErrNone)
  1276 					{
  1303 					{
  1277 					// try to allocate up to write cache size - this may not 
  1304 					// try to allocate up to write cache size - this may not 
  1278 					// be possible if a segment in the range is already cached
  1305 					// be possible if a segment in the range is already cached
  1601 	iLock.Signal();
  1628 	iLock.Signal();
  1602 	}
  1629 	}
  1603 
  1630 
  1604 void CFileCache::PropagateFlushErrorToAllFileShares()
  1631 void CFileCache::PropagateFlushErrorToAllFileShares()
  1605 	{
  1632 	{
  1606 	FileShares->Lock();
  1633 	ASSERT(IsDriveThread());
  1607 	TInt count = FileShares->Count();
  1634 	TDblQueIter<CFileShare> fileShareIter(iFileCB->FileShareList());
  1608 	while(count--)
  1635 	CFileShare* pFileShare;
  1609 		{
  1636 	while ((pFileShare = fileShareIter++) != NULL)
  1610 		CFileShare* share = (CFileShare*)(*FileShares)[count];
  1637 		{
  1611 		if (&share->File() == iFileCB)
  1638 		pFileShare->iFlushError = iFlushError;
  1612 			{
  1639 		}
  1613 			share->iFlushError = iFlushError;
       
  1614 			}
       
  1615 		}
       
  1616 	FileShares->Unlock();
       
  1617 	}
  1640 	}
  1618 
  1641 
  1619 /**
  1642 /**
  1620 CFileCache::DoFlushDirty()
  1643 CFileCache::DoFlushDirty()
  1621 
  1644 
  1813 					break;
  1836 					break;
  1814 					}
  1837 					}
  1815 
  1838 
  1816 #ifdef SETSIZE_BEFORE_WRITE	
  1839 #ifdef SETSIZE_BEFORE_WRITE	
  1817 				TInt64 physicalFileSize = iFileCB->Size64();
  1840 				TInt64 physicalFileSize = iFileCB->Size64();
  1818 				if ( (!iDrive->IsRugged()) && ((pos + (TInt64) len) > physicalFileSize))
  1841 				if ((pos + (TInt64) len) > physicalFileSize)
  1819 					{
  1842 					{
  1820 					// Need to switch to drive thread before calling CFileCB::SetSizeL()
  1843 					// Need to switch to drive thread before calling CFileCB::SetSizeL()
  1821 					if (!IsDriveThread())
  1844 					if (!IsDriveThread())
  1822 						{
  1845 						{
  1823 						aMsgRequest.SetState(CFsRequest::EReqStatePostInitialise);
  1846 						aMsgRequest.SetState(CFsRequest::EReqStatePostInitialise);
  1931 				switch((TFlushMode) (TInt) currentOperation->iScratchValue0)
  1954 				switch((TFlushMode) (TInt) currentOperation->iScratchValue0)
  1932 					{
  1955 					{
  1933 					case EFlushSingle:
  1956 					case EFlushSingle:
  1934 						currentOperation->iState = EStEnd;
  1957 						currentOperation->iState = EStEnd;
  1935 						break;
  1958 						break;
       
  1959 					case EFlushHalf:
       
  1960 						if (iCacheClient->LockedSegmentsHalfUsed())
       
  1961 							currentOperation->iState = EStWriteToDisk;
       
  1962 						else
       
  1963 							currentOperation->iState = EStEnd;
       
  1964 						break;
  1936 					case EFlushAll:
  1965 					case EFlushAll:
  1937 						currentOperation->iState = EStWriteToDisk;
  1966 						currentOperation->iState = EStWriteToDisk;
  1938 						break;
  1967 						break;
  1939 					default:
  1968 					default:
  1940 						ASSERT(0);
  1969 						ASSERT(0);
  2032 
  2061 
  2033 			// Without this code, retry will indiscriminately write over whatever disk happens to be present.
  2062 			// Without this code, retry will indiscriminately write over whatever disk happens to be present.
  2034 			// However if the write error is to the bootsector remounting will always fail because the boot
  2063 			// However if the write error is to the bootsector remounting will always fail because the boot
  2035 			// sector will have changed and hence the disk is useless.
  2064 			// sector will have changed and hence the disk is useless.
  2036 			// 
  2065 			// 
  2037 			TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMount, EF32TraceUidFileSys, DriveNumber());
  2066 			OstTrace1(TRACE_FILESYSTEM, FSYS_ECMOUNTCBREMOUNT2, "drive %d", DriveNumber());
  2038 
  2067 
  2039 			TInt remountSuccess = iDrive->ReMount(*iMount);
  2068 			TInt remountSuccess = iDrive->ReMount(*iMount);
  2040 
  2069 
  2041 			TRACE1(UTF::EBorder, UTraceModuleFileSys::ECMountCBReMountRet, EF32TraceUidFileSys, remountSuccess);
  2070 			OstTrace1(TRACE_FILESYSTEM, FSYS_ECMOUNTCBREMOUNT2RET, "success %d", remountSuccess);
  2042 			if (!remountSuccess)
  2071 			if (!remountSuccess)
  2043 				continue;
  2072 				continue;
  2044 			
  2073 			
  2045 			
  2074 			
  2046 			iMount->Drive().SetChanged(EFalse);
  2075 			iMount->Drive().SetChanged(EFalse);