--- a/remotestoragefw/remotefileengine/src/rsfwvolumetable.cpp Mon Jan 18 21:00:57 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1471 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: data struct for all volumes
-*
-*/
-
-
-#include <sysutil.h>
-#include <bautils.h>
-#include <rsfwmountman.h>
-#include <rsfwmountentry.h>
-
-#include "rsfwvolumetable.h"
-#include "rsfwvolume.h"
-#include "rsfwinterface.h"
-#include "rsfwmountstatemachine.h"
-#include "rsfwfileentry.h"
-#include "rsfwfiletable.h"
-#include "rsfwconfig.h"
-#include "rsfwfileengine.h"
-#include "rsfwrfeserver.h"
-
-#include "rsfwmountstore.h"
-#include "rsfwwaitnotemanager.h"
-#include "rsfwdormantmountloader.h"
-#include "mdebug.h"
-
-//CONSTANTS
-_LIT(KRsfwLruFileName, "lru.dat");
-_LIT(KRsfwRestorePendingMark, "rsfwmetadatarestorepending.dat");
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::NewL
-//
-// ----------------------------------------------------------------------------
-//
-CRsfwVolumeTable* CRsfwVolumeTable::NewL(CRsfwRfeServer* aRfeServer,
- CRsfwConfig* aRsfwConfig)
- {
- CRsfwVolumeTable* self = new (ELeave) CRsfwVolumeTable;
- DEBUGSTRING(("CRsfwVolumeTable: in NewL 0x%x", self));
- CleanupStack::PushL(self);
- self->ConstructL(aRfeServer, aRsfwConfig);
- CleanupStack::Pop(self);
- return self;
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::RestoreDormantMountsL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::RestoreDormantMountsL()
- {
- DEBUGSTRING(("CRsfwVolumeTable::RestoreDormantMountsL enter"));
- // Currently, we always enable persistence (used to be configurrable)
- iPermanence = ETrue;
- if (iPermanence)
- {
- // if restoring permanent state causes RFE panic, we must delete
- // the old permanent metadata and skip restoring it
- // otherwise RFE will just crash every time
- // Strategy is to add a file that tells that the process is ongoing.
- // If it is not able to finish successfully, we can conclude that there was a crash
- // marker is deleted from CRsfwDormantMountLoader, when we have succesfully also checked for dirty files
- TBool internalize = CheckAndAddProcessStartMarker();
- if (internalize)
- {
- WillLRUPriorityListBeInternalized();
- RestoreVolumesL();
- InternalizeLRUPriorityListL();
- }
- else
- {
- CleanupCorruptedCacheL();
- }
- }
- iDormantMountRestorePending = EFalse;
- DEBUGSTRING(("CRsfwVolumeTable::RestoreDormantMountsL exit"));
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::ConstructL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::ConstructL(CRsfwRfeServer* aRfeServer, CRsfwConfig* aRsfwConfig)
- {
- iRfeServer = aRfeServer;
- iRsfwConfig = aRsfwConfig;
-
- iAllEnginesIdle = ETrue;
-
- // set some local pointers for commonly used variable from CRsfwRfeServer::Env()
- iFs = CRsfwRfeServer::Env()->iFs;
- iCacheRoot = &(CRsfwRfeServer::Env()->iCacheRoot);
-
- TInt err = iRsfwConfig->Get(RsfwConfigKeys::KMaxCacheSize,
- iMaxCacheSize);
- if (err != KErrNone)
- {
- iMaxCacheSize = KDefaultMaxCacheSize;
- }
-
- err = iRsfwConfig->Get(RsfwConfigKeys::KMaxEntryCount,
- iMaxEntryCount);
- if (err != KErrNone)
- {
- iMaxEntryCount = KDefaultMaxEntryCount;
- }
-
- HBufC* confItem = HBufC::NewLC(KMaxRsfwConfItemLength);
- TPtr confItemPtr = confItem->Des();
-
- // global wait notes manager class
- // must be created before restoring the volumes
- iWaitNoteManager = CRsfwWaitNoteManager::NewL();
-
- RestoreDormantMountsL();
-
- err = iRsfwConfig->Get(RsfwConfigKeys::KFileCacheValidity,
- iFileCacheTimeout);
- if (err)
- {
- iFileCacheTimeout = KDefaultCacheValidity;
- }
- err = iRsfwConfig->Get(RsfwConfigKeys::KDirCacheValidity,
- iDirCacheTimeout);
- if (err)
- {
- iDirCacheTimeout = KDefaultDirCacheValidity;
- }
-
- err = iRsfwConfig->Get(RsfwConfigKeys::KRecognizerLimit,
- iRecognizerLimit);
- if (err)
- {
- iRecognizerLimit = KDefaultRecognizerLimit;
- }
-
- err = iRsfwConfig->Get(RsfwConfigKeys::KCachingMode, confItemPtr);
- if (err == KErrNone)
- {
- TLex lex(confItemPtr);
- TChar firstChar = lex.Get();
- firstChar.UpperCase();
- switch (firstChar)
- {
- case 'W':
- iCachingMode = EWholeFileCaching;
- break;
-
- case 'F':
- iCachingMode = EFullIfa;
- break;
-
- case 'M':
- default:
- iCachingMode = EMetadataIfa;
- break;
- }
- }
- else
- {
- // caching mode configuration entry not found
- iCachingMode = EMetadataIfa;
- }
- if (iCachingMode != EWholeFileCaching)
- {
- GetMimeTypeSpecificLimits();
- }
-
- err = iRsfwConfig->Get(RsfwConfigKeys::KInactivityTimeout,
- iInactivityTimeout);
- if (err)
- {
- iInactivityTimeout = KDefaultInactivityTimeout;
- }
-
- CleanupStack::PopAndDestroy(confItem);
-
- iMountStore = CRsfwMountStore::NewL(NULL);
-
- RProperty::Define(KRfeServerSecureUid,
- ERsfwPSKeyConnect,
- RProperty::EByteArray,
- KMaxDrives);
-
- iMountStateProperty.Attach(KRfeServerSecureUid,
- ERsfwPSKeyConnect);
-
-
- // this restores the dormant mounts asynchrously shortly after the server has started
- iDormantMountLoader = CRsfwDormantMountLoader::NewL(this);
- iDormantMountRestorePending = ETrue;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::~CRsfwVolumeTable
-//
-// ----------------------------------------------------------------------------
-//
-CRsfwVolumeTable::~CRsfwVolumeTable()
- {
- // save LRU list to the file
- ExternalizeLRUPriorityList();
-
- TInt i;
- DEBUGSTRING(("Deleting all volumes"));
- for (i = 0; i < KMaxVolumes; i++)
- {
- if (iVolumes[i])
- {
- delete iVolumes[i];
- }
- }
- delete iMountStore;
- iMountStateProperty.Close();
- if (iWaitNoteManager)
- {
- delete iWaitNoteManager;
- }
- if (iDormantMountLoader)
- {
- delete iDormantMountLoader;
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::DispatchL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::DispatchL(TAny* aIp, TAny* aOp)
- {
- TRfeInArgs* ip = reinterpret_cast<TRfeInArgs*>(aIp);
- TRfeOutArgs* op = reinterpret_cast<TRfeOutArgs*>(aOp);
- CRsfwFileEngine* fileEngine = NULL;
- TInt volumeId;
-
- if(ip->iOpCode == EFsRoot)
- {
- volumeId = iLastVolumeId;
- // boot - assume that ROOT
- // immediately follows after MountL()
- if (volumeId)
- {
- DEBUGSTRING(("Volume: acquired engine %d", volumeId));
- CRsfwVolume* volume = iVolumes[volumeId];
- if (volume)
- {
- fileEngine = volume->iFileEngine;
- }
- }
- }
- else
- {
- // iFid is always in the same position in the messages
- volumeId = static_cast<TRfeLookupInArgs*>(ip)->iFid.iVolumeId;
- CRsfwVolume* volume = VolumeByVolumeId(volumeId);
- if (volume)
- {
- fileEngine = volume->iFileEngine;
- }
- }
- if (fileEngine)
- {
- fileEngine->DispatchL(*ip, *op);
- }
- else
- {
- DEBUGSTRING(("Volume: no engine for %d", volumeId));
- User::Leave(KErrNotReady);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::VolumeIdByDriveLetter
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::VolumeIdByDriveLetter(TChar aDriveLetter)
- {
- TInt driveNumber;
- iFs.CharToDrive(aDriveLetter, driveNumber);
- if (driveNumber < 0) // note that 0 = EDriveA is allowed
- {
- driveNumber = KErrNotFound;
- }
- return driveNumber;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::VolumeByVolumeId
-//
-// ----------------------------------------------------------------------------
-//
-CRsfwVolume* CRsfwVolumeTable::VolumeByVolumeId(TInt aVolumeId)
- {
- if ((aVolumeId >= 0) && (aVolumeId < KMaxVolumes))
- {
- return iVolumes[aVolumeId];
- }
- return NULL;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::VolumeByDriveLetter
-//
-// ----------------------------------------------------------------------------
-//
-CRsfwVolume* CRsfwVolumeTable::VolumeByDriveLetter(TChar aDriveLetter)
- {
- return VolumeByVolumeId(VolumeIdByDriveLetter(aDriveLetter));
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::RecoverVolumeL
-//
-// ----------------------------------------------------------------------------
-//
-TUint CRsfwVolumeTable::RecoverVolumeL(const TRsfwMountConfig& aMountConfig,
- CRsfwMountStateMachine* aCaller)
- {
- DEBUGSTRING(("Recovering volume"));
- TUint transactionId = 0;
- CRsfwVolume* volume = VolumeByVolumeId(aCaller->iVolumeId);
- if (volume)
- {
- aCaller->iVolume = volume;
- // set also fileengine pointer in the state machine,
- // so that the operation can be cancelled
- aCaller->SetFileEngine(volume->iFileEngine);
- if (User::UpperCase(
- aCaller->iVolume->iMountInfo.iMountConfig.iDriveLetter) ==
- User::UpperCase(aMountConfig.iDriveLetter))
- {
- if (aCaller->iVolume->iMountInfo.iMountConfig.iFlags &
- KMountFlagOffLine)
- {
- // We are working offline
- aCaller->iVolume->iMountInfo.iMountStatus.iConnectionState =
- KMountNotConnected;
- }
- else
- {
- aCaller->iVolume->iMountInfo.iMountStatus.iConnectionState =
- KMountStronglyConnected;
- }
-
- transactionId =
- aCaller->iVolume->iFileEngine->RequestConnectionStateL(
- aCaller->iVolume->iMountInfo.iMountStatus.iConnectionState,
- aCaller);
- }
- else
- {
- User::Leave(KErrArgument);
- }
- }
- else
- {
- User::Leave(KErrNotFound);
- }
-
- return transactionId;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::MountState
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::MountState(TChar aDriveLetter)
- {
- DEBUGSTRING(("Getting mount state"));
- TInt state;
- // Find the volume
- CRsfwVolume* volume = VolumeByDriveLetter(aDriveLetter);
- if (volume)
- {
- TRsfwMountInfo& mountInfo = volume->iMountInfo;
- DEBUGSTRING16(("mount '%S'in state %d",
- &mountInfo.iMountConfig.iName,
- mountInfo.iMountStatus.iMountState));
- state = mountInfo.iMountStatus.iMountState;
- }
- else
- {
- DEBUGSTRING(("mount not found"));
- state = 0; // define KMountStateNone=0 in RsfwControl.h
- }
- return state;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::GetMountConfigL
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::GetMountConfigL(TRsfwMountConfig& aMountConfig)
- {
- DEBUGSTRING16(("Getting mount config for name '%S', drive %c",
- &aMountConfig.iName,
- TUint(aMountConfig.iDriveLetter)));
- TInt err = KErrNone;
- const CRsfwMountEntry* entry =
- iMountStore->LookupEntryByDriveL(aMountConfig.iDriveLetter);
- if (!entry)
- {
- // Could not find by drive letter - retry with name
- entry = iMountStore->LookupEntryByNameL(aMountConfig.iName);
- }
- if (entry &&
- entry->Item(EMountEntryItemDrive) &&
- entry->Item(EMountEntryItemUri))
- {
- if (entry->Item(EMountEntryItemDrive)->Length())
- {
- TLex parse(*entry->Item(EMountEntryItemDrive));
- aMountConfig.iDriveLetter = parse.Get();
- if (entry->Item(EMountEntryItemName))
- {
- aMountConfig.iName.Copy(*entry->Item(EMountEntryItemName));
- }
- else
- {
- aMountConfig.iName.SetLength(0);
- }
- aMountConfig.iUri.Copy(*entry->Item(EMountEntryItemUri));
- if (entry->Item(EMountEntryItemUserName))
- {
- aMountConfig.iUserName.Copy(
- *entry->Item(EMountEntryItemUserName));
- }
- else
- {
- aMountConfig.iUserName.SetLength(0);
- }
-
- if (entry->Item(EMountEntryItemPassword))
- {
- aMountConfig.iPassword.Copy(
- *entry->Item(EMountEntryItemPassword));
- }
- else
- {
- aMountConfig.iPassword.SetLength(0);
- }
-
- if (entry->Item(EMountEntryItemIap))
- {
- aMountConfig.iAuxData.Copy(
- *entry->Item(EMountEntryItemIap));
- }
- else
- {
- aMountConfig.iAuxData.SetLength(0);
- }
-
- TInt inactivityTimeout = iInactivityTimeout;
- if (entry->Item(EMountEntryItemInactivityTimeout))
- {
- TLex timeout(*entry->Item(EMountEntryItemInactivityTimeout));
- timeout.Val(inactivityTimeout);
- DEBUGSTRING(("Set inactivity timeout = %d",
- inactivityTimeout));
- }
- aMountConfig.iInactivityTimeout = inactivityTimeout;
-
- aMountConfig.iFlags = 0;
- }
- else
- {
- err = KErrArgument;
- }
- }
- else
- {
- DEBUGSTRING(("mount configuration not found"));
- err = KErrNotFound;
- }
-
- return err;
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::RestoreVolumesL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::RestoreVolumesL()
- {
- DEBUGSTRING(("CRsfwVolumeTable::RestoreVolumesL"));
- // Load persistently stored volumes
- CDir* dirList;
- TInt err = iFs.GetDir(*iCacheRoot,
- KEntryAttMaskSupported,
- ESortByName,
- dirList);
- CleanupStack::PushL(dirList);
- DEBUGSTRING(("GetDir for cacheRoot returned %d", err));
- if (err == KErrNone)
- {
- TInt i;
- for (i = 0; i < dirList->Count(); i++)
- {
- const TEntry& entry = (*dirList)[i];
- if (entry.iAtt & KEntryAttDir)
- {
- // The name of cache directories are C<volume_id>
- _LIT(KCacheMatch, "C*");
- if (entry.iName.Match(KCacheMatch) == 0)
- {
- TLex volumeAlpha(entry.iName.Mid(1));
- TInt volumeId;
- err = volumeAlpha.Val(volumeId);
- if ((err == KErrNone) &&
- (volumeId >= 0) &&
- (volumeId < KMaxVolumes))
- {
- TRsfwMountConfig* mountConfig = new (ELeave) TRsfwMountConfig;
- CleanupStack::PushL(mountConfig);
- HBufC* metaDataPath = HBufC::NewLC(KMaxPath);
- TPtr metaDataPathPtr = metaDataPath->Des();
- metaDataPathPtr.Copy(*iCacheRoot);
- metaDataPathPtr.Append(entry.iName);
- metaDataPathPtr.Append('\\');
- metaDataPathPtr.Append(KMetaDataFileName);
- CRsfwMetaDataStore* metaDataStore =
- CRsfwMetaDataStore::NewLC(metaDataPathPtr);
- // Get the mount configuration info from the
- // persistent store
- TRAP(err,
- metaDataStore->GetMountConfigL(*mountConfig));
- // metaDataStore, metaDataPath
- CleanupStack::PopAndDestroy(2);
- if (err == KErrNone)
- {
- DEBUGSTRING16(("Restoring '%S' as volume %d'",
- &mountConfig->iUri,
- volumeId));
- TRAP_IGNORE(MountDormantL(*mountConfig,
- volumeId));
- // In case of error, we should clear the cache
- }
- CleanupStack::PopAndDestroy(mountConfig);
- }
- }
- }
- }
- }
- CleanupStack::PopAndDestroy(dirList); // dirList
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::DismountByVolumeId
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::DismountByVolumeIdL(TInt aVolumeId,
- TBool aDiscardPermanentData)
- {
- DEBUGSTRING(("Dismounting volume %d", aVolumeId));
- CRsfwVolume* volume = VolumeByVolumeId(aVolumeId);
- if (volume)
- {
- if (aDiscardPermanentData)
- {
- // Delete also the meta data
- CRsfwFileEngine* fileEngine = volume->iFileEngine;
- if (fileEngine)
- {
- // Clear cache of files and meta data
- fileEngine->SetPermanenceL(EFalse);
- if (!volume->iMountInfo.iMountStatus.iPermanence)
- {
- // There was no change in the above -
- // so, we have to clear the cache explicitly
- fileEngine->iFileTable->SetupCacheL();
- }
- }
- }
- delete volume;
- iVolumes[aVolumeId] = NULL;
- }
- else
- {
- User::Leave(KErrNotFound);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::DismountByDriveLetter
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::DismountByDriveLetterL(TChar aDriveLetter,
- TBool aDiscardPermanentData)
- {
- DEBUGSTRING(("Dismounting drive %c", TUint(aDriveLetter)));
- CRsfwVolume* volume = VolumeByDriveLetter(aDriveLetter);
- if (volume)
- {
- DismountByVolumeIdL(volume->iMountInfo.iMountStatus.iVolumeId,
- aDiscardPermanentData);
- }
- else
- {
- User::Leave(KErrNotFound);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::GetMountList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::GetMountList(TDriveList& aMountList)
- {
- aMountList.Zero();
- TInt i;
- for (i = 0; i < KMaxVolumes; i++)
- {
- if (iVolumes[i])
- {
- aMountList.Append(iVolumes[i]->
- iMountInfo.iMountConfig.iDriveLetter);
- }
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::GetMountInfo
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::GetMountInfo(TRsfwMountInfo& aMountInfo)
- {
- CRsfwVolume* volume =
- VolumeByDriveLetter(aMountInfo.iMountConfig.iDriveLetter);
- if (volume)
- {
- volume->GetMountInfo(aMountInfo);
- return KErrNone;
- }
- return KErrNotFound;
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::GetMimeTypeSpecificLimits
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::GetMimeTypeSpecificLimits()
- {
- TInt err;
- err = iRsfwConfig->Get(RsfwConfigKeys::KImgJpegLimit, iImageJpegLimit);
- if (err != KErrNone)
- {
- iImageJpegLimit = KDefaultJpegLimit;
- }
-
- err = iRsfwConfig->Get(RsfwConfigKeys::KAudMpegLimit, iAudioMpegLimit);
- if (err)
- {
- iAudioMpegLimit = KDefaultMpegLimit;
- }
- }
-
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::EnsureCacheCanBeAddedL
-//
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::EnsureCacheCanBeAddedL(TInt aBytes)
- {
- DEBUGSTRING(("CACHE MANAGER: ensure that %d bytes can be added to cache",
- aBytes));
- DEBUGSTRING(("CACHE MANAGER: total cached size is currently %d",
- TotalCachedSize()));
- DEBUGSTRING(("CACHE MANAGER: max cache size is %d", iMaxCacheSize));
-
-
- // FIRST: Is there enough space on the cache drive to store the new data
- TInt cacheDrive = CRsfwRfeServer::Env()->iCacheDrive;
- TBool isDiskFull = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs,
- aBytes,
- cacheDrive);
- if ( isDiskFull )
- {
- // check whether clearing cache may help at all
- if ( aBytes > TotalCachedSize() )
- {
- isDiskFull = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs,
- aBytes - TotalCachedSize(),
- cacheDrive);
- if ( isDiskFull )
- {
- DEBUGSTRING(("CACHE MANAGER: no space on disk"));
- return EFalse;
- }
- }
- // seems that clearing cache may help
- else
- {
- DEBUGSTRING(("CACHE MANAGER: running out of disk space, attempting to purge some bytes from cache"));
- do
- {
- CRsfwFileEntry* victim = iLRUPriorityList.GetAndRemoveFirstEntry();
-
- if (!victim)
- {
- DEBUGSTRING(("CACHE MANAGER: nothing to delete!!!"));
- return EFalse; // cannot clear enough cache space
- }
-
- DEBUGSTRING(("CACHE MANAGER: removing fid %d from the cache ",
- victim->Fid().iNodeId));
-
- TDesC* cacheNamep = victim->CacheFileName();
- User::LeaveIfError(iFs.Delete(*cacheNamep));
-
- victim->SetCached(EFalse);
- victim->iCachedSize = 0;
- victim->Parent()->SetLocallyDirty();
-
-
- isDiskFull = SysUtil::DiskSpaceBelowCriticalLevelL(&iFs,
- aBytes,
- cacheDrive);
- }
- while ( isDiskFull );
- }
- }
-
- // SECOND: is there enough space in the cache
- if (TotalCachedSize() + aBytes > iMaxCacheSize)
- {
- TInt bytesDeleted = 0;
- TInt bytesToBeDeleted = TotalCachedSize() + aBytes - iMaxCacheSize;
- DEBUGSTRING(("CACHE MANAGER: attempting to purge %d bytes from cache",
- bytesToBeDeleted));
-
- while (bytesDeleted < bytesToBeDeleted)
- {
- CRsfwFileEntry* victim = iLRUPriorityList.GetAndRemoveFirstEntry();
-
- if (!victim)
- {
- DEBUGSTRING(("CACHE MANAGER: XXXX: nothing to delete!!!"));
- return EFalse; // cannot clear enough cache space
- }
-
- DEBUGSTRING(("CACHE MANAGER: removing fid %d from the cache ",
- victim->Fid().iNodeId));
-
- TDesC* cacheNamep = victim->CacheFileName();
- TInt victimSize = victim->iCachedSize;
- User::LeaveIfError(iFs.Delete(*cacheNamep));
-
- victim->SetCached(EFalse);
- victim->iCachedSize = 0;
- victim->Parent()->SetLocallyDirty();
-
- bytesDeleted = bytesDeleted + victimSize;
- }
- }
-
- return ETrue;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::EnsureMetadataCanBeAddedL
-// This function is called at any time a new CRsfwFileEntry object is about to
-// be created in memory.
-// However we want to prevent the scenario in which parent entry is deleted
-// just before its kid creation.
-// That's why function takes as a parameter a parent entry for the entry
-// that is about to be created.
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::EnsureMetadataCanBeAddedL(CRsfwFileEntry* aParent)
- {
- DEBUGSTRING(("memory cap: number of entries %d, entry limit: %d",
- TotalEntryCount(), iMaxEntryCount));
-
- TBool parentFound = EFalse;
-
- while ( TotalEntryCount() >= iMaxEntryCount )
- {
- CRsfwFileEntry* victim = iMetadataLRUPriorityList.GetAndRemoveFirstEntry();
-
- // if no entries to delete on metadata LRU list try to remove item from file cache LRU list
- if (!victim)
- {
- victim = iLRUPriorityList.GetAndRemoveFirstEntry();
-
- if (!victim)
- {
- DEBUGSTRING(("memory cap: nothing to delete!!!"));
- return EFalse; // no posibility to add new entry
- }
- }
-
- // don't touch the root items
- if ( IsRoot(victim) )
- {
- continue;
- }
-
- // if we've found the parent don't touch it, just find the other victim ...
- if (victim && aParent && victim == aParent)
- {
- DEBUGSTRING(("<<<<< SAVED THE PARENT!!!! >>>>"));
- parentFound = ETrue;
- continue;
- }
-
-
- // destroy the item
- DEBUGSTRING(("memory cap: removing fid %d from memory",
- victim->Fid().iNodeId));
- // victim's parent metadata will become out-of-date if we remove victim from memory
- if ( victim->Parent() )
- {
- victim->Parent()->iUseCachedData = EFalse;
- }
-
- victim->DropLD();
- }
-
- // put the parent back to the list if it was removed from the list.
- // the reason is that at this point we are not sure whether child will be in fact created.
- // for now we were only interested in preventing the parent from being deleted, nothing more
- // as soon as the child is created, the parent will be removed from the list anyway
- if (parentFound)
- {
- iMetadataLRUPriorityList.AddNodeL(aParent, ECachePriorityNormal);
- }
-
- return ETrue;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::IsRoot
-// Checks whether given entry is a root of some file table
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::IsRoot(const CRsfwFileEntry* aEntry)
- {
- if (!aEntry)
- {
- return EFalse;
- }
-
- TInt i;
- for ( i = 0; i < KMaxVolumes; i++ )
- {
- CRsfwVolume* volume;
- volume = iVolumes[i];
- if ( volume && aEntry == volume->iFileEngine->iFileTable->Root())
- {
- return ETrue;
- }
- }
- return EFalse;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::TotalCachedSize
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::TotalCachedSize()
- {
- TInt totalSize = 0;
- CRsfwVolume* volume;
- TInt i = 0;
- while (i < KMaxVolumes)
- {
- volume = iVolumes[i];
- if (volume)
- {
- TInt newSize = volume->iFileEngine->iFileTable->TotalCachedSize();
- totalSize += newSize;
- }
- i++;
- }
- return totalSize;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::TotalEntryCount
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::TotalEntryCount()
- {
- TInt totalCount = 0;
- CRsfwVolume* volume;
- for ( TInt i = 0; i < KMaxVolumes; i++ )
- {
- volume = iVolumes[i];
- if (volume)
- {
- TInt volumeCount = volume->iFileEngine->iFileTable->TotalEntryCount();
- totalCount += volumeCount;
- }
- }
- return totalCount;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::AddToLRUPriorityListL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::AddToLRUPriorityListL(CRsfwFileEntry *aFe, TInt aPriority)
- {
- DEBUGSTRING(("CACHE MANAGER: adding fid '%d' to the LRU cache",
- aFe->Fid().iNodeId));
- iLRUPriorityList.AddNodeL(aFe, aPriority);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::RemoveFromLRUPriorityList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::RemoveFromLRUPriorityList(CRsfwFileEntry *aFe)
- {
- DEBUGSTRING(("CACHE MANAGER: removing fid '%d' from the LRU cache",
- aFe->Fid().iNodeId));
- iLRUPriorityList.RemoveNode(aFe);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::AddToMetadataLRUPriorityListL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::AddToMetadataLRUPriorityListL(CRsfwFileEntry *aFe, TInt aPriority)
- {
- DEBUGSTRING(("memory cap: adding fid '%d' to the metadata LRU list",
- aFe->Fid().iNodeId));
- iMetadataLRUPriorityList.AddNodeL(aFe, aPriority);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::RemoveFromMetadataLRUPriorityList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::RemoveFromMetadataLRUPriorityList(CRsfwFileEntry *aFe)
- {
- DEBUGSTRING(("CRsfwVolumeTable::RemoveFromMetadataLRUPriorityList"));
- iMetadataLRUPriorityList.RemoveNode(aFe);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::MoveToTheBackOfMetadataLRUPriorityList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::MoveToTheBackOfMetadataLRUPriorityListL(CRsfwFileEntry *aFe)
- {
- // just try to remove the entry from the list and if it was on the list then append it again
- if ( iMetadataLRUPriorityList.RemoveNode(aFe) == KErrNone )
- {
- DEBUGSTRING(("memory cap: moving fid '%d' to the back of metadata LRU list",
- aFe->Fid().iNodeId));
- iMetadataLRUPriorityList.AddNodeL(aFe, ECachePriorityNormal);
- }
- }
-
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::CheckAndAddProcessStartMarker
-//
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::CheckAndAddProcessStartMarker()
- {
- DEBUGSTRING(("CRsfwVolumeTable::CheckAndAddProcessStartMarker"));
- TFileName path;
- path.Copy(*iCacheRoot);
- path.Append(KRsfwRestorePendingMark);
-
- if (BaflUtils::FileExists(iFs, path))
- {
- // file already exists, the previous attempt to restore metadata must have failed
- DEBUGSTRING(("returning EFalse; file already exists"));
- return EFalse;
- }
- else
- {
- // create an empty file
- TInt err;
- RFile markerFile;
- err = markerFile.Create(iFs, path, EFileWrite);
- if (err)
- {
- return EFalse;
- }
- else
- {
- DEBUGSTRING(("returning ETrue; file created"));
- markerFile.Close();
- return ETrue;
- }
-
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::DeleteTheMarker
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::DeleteTheMarker()
- {
- TFileName path;
- path.Copy(*iCacheRoot);
- path.Append(KRsfwRestorePendingMark);
-
- // ignore the error
- // if this fails for some reason, lets allow the file to be there
- // as "something" must be wrong
- iFs.Delete(path);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::CleanupCorrutedCacheL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::CleanupCorruptedCacheL()
- {
- // delete everything from the cache
- TFileName cachepath;
- cachepath.Copy(*iCacheRoot);
- CFileMan* fileMan = CFileMan::NewL(iFs);
- fileMan->Delete(cachepath, CFileMan::ERecurse);
- delete fileMan;
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::WillExternalizedLRUPriorityListBeUsed
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::WillLRUPriorityListBeInternalized()
- {
- DEBUGSTRING(("CRsfwVolumeTable::WillLRUPriorityListBeInternalized"));
- iUseExternalizedLRUList = EFalse;
- // check whether the file with externalized data exists
- TFileName path;
- path.Copy(*iCacheRoot);
- path.Append(KRsfwLruFileName);
-
- if (BaflUtils::FileExists(iFs, path))
- {
- iUseExternalizedLRUList = ETrue;
- }
- DEBUGSTRING(("...set to %d", iUseExternalizedLRUList));
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::ExternalizeLRUPriorityList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::ExternalizeLRUPriorityList()
- {
- TRAPD(err, ExternalizeLRUPriorityListL());
- if (err)
- {
- DEBUGSTRING(("Externalizing LRU priority list failed!"));
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::ExternalizeLRUPriorityList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::ExternalizeLRUPriorityListL()
- {
- // prepare temp path
- _LIT(KRsfwLruTempFileName, "lru.temp");
- TFileName tempPath;
- tempPath.Copy(*iCacheRoot);
- tempPath.Append(KRsfwLruTempFileName);
-
- // create temp file
- RFile file;
- CleanupClosePushL(file);
- User::LeaveIfError(file.Replace(iFs, tempPath, EFileShareAny | EFileWrite));
-
- // associate stream
- RFileWriteStream stream(file);
- CleanupClosePushL(stream);
-
- // externalize
- iLRUPriorityList.ExternalizeL(stream);
- stream.CommitL();
-
- // cleanup
- CleanupStack::PopAndDestroy(2); // stream, file
-
- // everything went ok -> rename lru.temp into lru.dat
- TFileName path;
- path.Copy(*iCacheRoot);
- path.Append(KRsfwLruFileName);
- CFileMan* fm = CFileMan::NewL(iFs);
- CleanupStack::PushL(fm);
- TInt err = fm->Rename(tempPath, path, CFileMan::EOverWrite);
- if (err)
- {
- fm->Delete(tempPath);
- fm->Delete(path);
- User::Leave(err);
- }
- CleanupStack::PopAndDestroy(fm);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::InternalizeLRUPriorityList
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::InternalizeLRUPriorityListL()
- {
- if (!iUseExternalizedLRUList)
- {
- // it means LRU has been already populated when loading metadata
- // so nothing to do here
- return;
- }
- // prepare path
- TFileName path;
- path.Copy(*iCacheRoot);
- path.Append(KRsfwLruFileName);
-
- // open file
- RFile file;
- TInt err = file.Open(iFs, path, EFileShareAny | EFileRead);
- if ( err == KErrNone )
- {
- CleanupClosePushL(file);
-
- // associate stream
- RFileReadStream stream(file);
- CleanupClosePushL(stream);
-
- // internalize
- TRAP(err, iLRUPriorityList.InternalizeL(stream, this));
-
- // cleanup
- CleanupStack::PopAndDestroy(2); // stream, file
- }
-
- DEBUGSTRING(("InternalizeLRUPriorityListL: status %d", err));
-
- // once internalizing is done, the file is not needed anymore
- // ignore the result
- iFs.Delete(path);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::OperationCompleted()
-// This function may shut down RFE.
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::OperationCompleted(CRsfwVolume* /* aVolume */)
- {
- DEBUGSTRING(("Volume operation completed"));
- // Shut down the whole server if all remaining mounts are dormant
- // and we are not still restoring dormant mounts
- if ((iAllEnginesIdle) && (!iDormantMountRestorePending))
- {
- iRfeServer->AllEnginesIdling(KRsfwDormantShutdownTimeout);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::VolumeStateChanged()
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::VolumeStateChanged(CRsfwVolume* aVolume)
- {
- DEBUGSTRING(("Volume state changed"));
-
- TBool allEnginesIdle = ETrue;
- TInt i = 0;
- do
- {
- if (iVolumes[i])
- {
- if (!IsMountIdle(iVolumes[i]->iMountInfo.iMountStatus))
- {
- // Do not shut down if there are connected mounts
- allEnginesIdle = EFalse;
- }
- }
- } while ((++i < KMaxVolumes) && allEnginesIdle);
-
- // one more thing is to check the current volume since
- // if the drive was newly mounted, it will not be found from the volume table
- if (allEnginesIdle)
- {
- TInt driveNumber = VolumeIdByDriveLetter(aVolume->MountInfo()->iMountConfig.iDriveLetter);
- if ((driveNumber != KErrNotFound) &&
- (!IsMountIdle(aVolume->MountInfo()->iMountStatus)))
- {
- allEnginesIdle = EFalse;
- }
- }
-
- DEBUGSTRING(("All engines idle = %d", allEnginesIdle));
- iAllEnginesIdle = allEnginesIdle;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::PublishConnectionStatus()
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::PublishConnectionStatus(CRsfwVolume* aVolume)
- {
- DEBUGSTRING(("Publishing connection status:"));
- TDriveList driveList;
- driveList.FillZ(driveList.MaxLength());
- TInt i;
- // (at least) record the state of the volume received as a parameter
- // (if the drive was newly mounted, it will not be found from the volume table
- TInt driveNumber = VolumeIdByDriveLetter(aVolume->MountInfo()->iMountConfig.iDriveLetter);
- if ((driveNumber != KErrNotFound) &&
- (aVolume->MountInfo()->iMountStatus.iMountState != KMountStateDormant))
- {
- DEBUGSTRING(("- connected: %c", TUint(aVolume->MountInfo()->iMountConfig.iDriveLetter)));
- driveList[driveNumber] = 1;
- }
-
- // for convenience, record the states of other volumes too from the volume table
- for (i = 0; i < KMaxVolumes; i++)
- {
- if (iVolumes[i])
- {
- TRsfwMountInfo& mountInfo = iVolumes[i]->iMountInfo;
- if (mountInfo.iMountStatus.iMountState != KMountStateDormant)
- {
- driveNumber =
- VolumeIdByDriveLetter(mountInfo.iMountConfig.iDriveLetter);
- if (driveNumber != KErrNotFound)
- {
- DEBUGSTRING(("- connected: %c",
- TUint(mountInfo.iMountConfig.iDriveLetter)));
- driveList[driveNumber] = 1;
- }
- }
- }
- }
-
- iMountStateProperty.Set(driveList);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::WaitNoteManager()
-//
-// ----------------------------------------------------------------------------
-//
-CRsfwWaitNoteManager* CRsfwVolumeTable::WaitNoteManager()
- {
- return iWaitNoteManager;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::IsCachedDataStillValid()
-//
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::IsCachedDataStillValid(TTime aCachedTime)
- {
- return IsCacheStillValid(aCachedTime,
- TTimeIntervalSeconds(iFileCacheTimeout));
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::IsCachedAttrStillValid()
-//
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::IsCachedAttrStillValid(TTime aCachedTime)
- {
- return IsCacheStillValid(aCachedTime,
- TTimeIntervalSeconds(iDirCacheTimeout));
- }
-
-
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::MountDormantL
-//
-// ----------------------------------------------------------------------------
-//
-void CRsfwVolumeTable::MountDormantL(const TRsfwMountConfig& aMountConfig,
- TInt aVolumeId)
- {
- // Bind a volume id to a file engine
- DEBUGSTRING16(("Restoring drive '%c' with uri '%S' and flags 0x%x",
- TUint(aMountConfig.iDriveLetter),
- &aMountConfig.iUri,
- aMountConfig.iFlags));
-
- // Create a file engine for the volume
- CRsfwVolume* volume = new (ELeave) CRsfwVolume();
- CleanupStack::PushL(volume);
- volume->iMountInfo.iMountConfig = aMountConfig;
- volume->iMountInfo.iMountStatus.iVolumeId = aVolumeId;
- volume->iVolumeTable = this;
- volume->iMountInfo.iMountStatus.iPermanence = iPermanence;
- // We are working offline
- volume->iMountInfo.iMountStatus.iMountState = KMountStateDormant;
- volume->iMountInfo.iMountStatus.iConnectionState = KMountNotConnected;
- CRsfwFileEngine* fileEngine = CRsfwFileEngine::NewL(volume);
- volume->iFileEngine = fileEngine;
- delete iVolumes[aVolumeId];
- iVolumes[aVolumeId] = volume;
- CleanupStack::Pop(volume);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::IsCachedAttrStillValid()
-//
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::IsCacheStillValid(TTime aCachedTime,
- TTimeIntervalSeconds aValidity)
- {
- TTime now;
- TTime comp;
-
- now.UniversalTime();
- comp = now - aValidity;
-
- if (comp >= aCachedTime)
- {
- return EFalse;
- }
- else
- {
- return ETrue;
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::PurgeFromCache()
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::PurgeFromCache(TDesC& aCachePath)
- {
- // get the volume id for this path
- TParse parser;
- parser.Set(aCachePath, NULL, NULL);
- if (!(parser.DrivePresent()))
- {
- return KErrArgument;
- }
- TPtrC drive = parser.Drive();
- CRsfwVolume* volume = VolumeByDriveLetter(drive[0]);
- if (!volume)
- {
- return KErrNotFound;
- }
-
- if (!(parser.PathPresent()))
- {
- return KErrArgument;
- }
-
- if (parser.NamePresent())
- {
- // this is a file
- return KErrArgument;
- }
- return volume->iFileEngine->PurgeFromCache(parser.Path());
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::CancelTransfer()
-//
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwVolumeTable::CancelTransferL(TDesC& aFilePath)
- {
- DEBUGSTRING16(("CRsfwVolumeTable::CancelTransferL for %S", &aFilePath));
- // get the volume id for this path
- TParse parser;
- parser.Set(aFilePath, NULL, NULL);
- if (!(parser.DrivePresent()))
- {
- return KErrArgument;
- }
- TPtrC drive = parser.Drive();
- CRsfwVolume* volume = VolumeByDriveLetter(drive[0]);
- if (!volume)
- {
- return KErrNotFound;
- }
-
- if (!(parser.NamePresent()))
- {
- // this is not a file
- return KErrArgument;
- }
-
-
- // mark the file entry as "cancelled"
- TPtrC pathPtr = aFilePath.Right(aFilePath.Length() - 2); //drop the drive letter
- CRsfwFileEntry* targetFid = volume->iFileEngine->FetchFep(pathPtr);
- if (targetFid)
- {
- DEBUGSTRING(("setting KNodeWritingCancelled for fid %d", targetFid->Fid().iNodeId));
- targetFid->SetFlags(KNodeWritingCancelled);
- }
-
- volume->iFileEngine->CancelTransactionL(aFilePath);
-
- return KErrNone;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwVolumeTable::IsMountIdle()
-//
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwVolumeTable::IsMountIdle(TRsfwMountStatus& aMountStatus)
- {
- if (aMountStatus.iMountState != KMountStateDormant
- || aMountStatus.iConnectionState == KMountConnecting)
- {
- return EFalse;
- }
- else
- {
- return ETrue;
- }
- }