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