diff -r ff5437e4337c -r 48e57fb1237e userlibandfileserver/fileserver/sfile/sf_drv.cpp --- a/userlibandfileserver/fileserver/sfile/sf_drv.cpp Wed Oct 06 17:13:14 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_drv.cpp Mon Oct 11 17:54:41 2010 +0100 @@ -130,6 +130,10 @@ iMount=TheContainer->CreateL(); TInt r=iLock.CreateLocal(); User::LeaveIfError(r); + + iDeferredDismountRequest = new(ELeave) CFsInternalRequest; + iDeferredDismountRequest->Set(DeferredDismountOp,NULL); + iDeferredDismountRequest->SetDriveNumber(aDriveNumber); } TInt TDrive::CheckMountAndEntryName(const TDesC& aName) @@ -2345,10 +2349,66 @@ { return(iDismountLock); } +/** +DismountClientAdded() - + +Increments the count of clients which need to respond to a dismount request - by calling RFs::AllowDismount() - +before the dismount can process + +Called when a EFsDismountRegisterClient request is completed by RFs::NotifyDismount(,,EFsDismountNotifyClients) +*/ +void TDrive::DismountClientAdded() + { + __e32_atomic_add_ord32(&iDismountClientCount, (TUint32) 1); + } + +/** +DismountClientRemoved() - +Called when a EFsDismountRegisterClient request is deleted. E.g. by RFs::AllowDismount() +*/ +void TDrive::DismountClientRemoved() + { + ASSERT(iDismountClientCount > 0); + if ((__e32_atomic_add_ord32(&iDismountClientCount, (TUint32) -1) == 1) && + (!FsThreadManager::IsDriveThread(iDriveNumber,EFalse)) && + DismountDeferred()) + { + iDeferredDismountRequest->Dispatch(); + } + } + +TInt TDrive::DismountClientCount() + { + return iDismountClientCount; + } + + +/* +Dismount the file system if a deferred dismount has been schedulued and there are no waiting clients and no clamps +*/ +TInt TDrive::DeferredDismountCheck() + { + // Don't dismount if no deferred dismount is scheduled + if (!DismountDeferred()) + return KErrNone; + + // Don't dismount if clients are waiting + if (DismountClientCount() > 0) + return KErrNone; + + // Don't dismount if files are clamped + TInt clampErr = ClampsOnDrive(); + if (clampErr != 0 && clampErr != KErrNotSupported) + return KErrNone; + + // Nothing to wait for, so dismount immediately + __ASSERT_DEBUG(GetFSys(), Fault(EAllowDismount)); + return DeferredDismount(); + } /** -Pending flag - set while waiting for clients to accept the dismount +Dismount deferred flag - set while waiting for clients to accept the dismount or files to become unclamped */ void TDrive::SetDismountDeferred(TBool aPending) { @@ -2529,19 +2589,7 @@ //---------------------------------------------------------------------------- /** - Complete, remove and delete notification requests - @param aCompletionCode completion code for some notifications -*/ -void TDrive::DoCompleteDismountNotify(TInt aCompletionCode) - { - FsNotify::HandleDismount(EFsDismountRegisterClient, iDriveNumber, ETrue, KErrNone); - FsNotify::HandleDismount(EFsDismountNotifyClients, iDriveNumber, ETrue, aCompletionCode); - FsNotify::HandleDismount(EFsDismountForceDismount, iDriveNumber, ETrue, aCompletionCode); - } - -//---------------------------------------------------------------------------- -/** - a helper method that allows forced dismounting current mount for volume formatting. + a helper method that allows forced unmounting current mount for volume formatting. */ TInt TDrive::ForceUnmountFileSystemForFormatting() { @@ -2566,8 +2614,6 @@ ForceDismount(); - DoCompleteDismountNotify(KErrDisMounted); //-- complete all dismount notifications - return KErrNone; }