equal
deleted
inserted
replaced
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); |