userlibandfileserver/fileserver/sfat32/inc/fat_table32.h
changeset 0 a41df078684a
child 6 0173bcd7697c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfat32/inc/fat_table32.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,427 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// f32\sfat32\inc\fat_table32.h
+// FAT32 File Allocation Table classes definitions
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef FAT_TABLE_32_H
+#define FAT_TABLE_32_H
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+
+class CFatHelperThreadBase;
+class CFat32ScanThread;
+
+TInt FAT32_ScanThread(TAny* apHostObject);
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+
+/**
+    Fat table abstraction for all media types except RAM.
+    Supports FAT12/16/32
+*/
+class CAtaFatTable : public CFatTable
+    {
+
+public:
+    
+    static CAtaFatTable* NewL(CFatMountCB& aOwner);
+    ~CAtaFatTable();
+
+    //-- overrides from th ebase class
+    TUint32 ReadL(TUint32 aFatIndex) const;
+    void WriteL(TUint32 aFatIndex, TUint32 aValue);
+    void MountL(const TMountParams& aMountParam);
+
+    TInt64 DataPositionInBytes(TUint32 aCluster) const;
+
+    void InitializeL();
+    void Dismount(TBool aDiscardDirtyData);
+    void FlushL();
+    
+    void InvalidateCacheL();
+    void InvalidateCacheL(TInt64 aPos, TUint32 aLength);
+
+    TUint32 FreeClusterHint() const;
+    TUint32 NumberOfFreeClusters(TBool aSyncOperation=EFalse) const;
+
+    TBool ConsistentState() const;
+
+    inline void AcquireLock() const {iDriveInteface.AcquireLock();} 
+    inline void ReleaseLock() const {iDriveInteface.ReleaseLock();} 
+    
+    inline TFatDriveInterface& DriveInterface() const;
+    inline CFatMountCB* OwnerMount() const;
+
+
+private:
+    
+    /** internal states of this object */
+    enum TState
+        {
+        ENotInitialised,    ///< 0 initial invalid state
+        EInitialised,       ///< 1 initialised, i.e. internal objects created, but unusable becasue number of free entries isn't known
+        EMounting,          ///< 2 mounting started
+        EMounted,           ///< 3 successfully mounted; number of free entries is known. This is the only consistent state.
+        EDismounted,        ///< 4 FAT table object is dismounted
+        EFreeClustersScan,  ///< 5 FAT32 scan thread is currently scanning FAT table for free clusters
+        EMountAborted       ///< 6 Mounting failed, probably because of FAT32 free clusters scan thread failure.
+        };
+
+public:
+
+    /** A helper class used in FAT scanning for free clusters*/
+    class TFatScanParam
+        {
+    public:
+        inline TFatScanParam();
+
+    public:
+        TUint32 iEntriesScanned;        ///< total number of FAT entries scanned by DoParseFatBuf()
+        TUint32 iFirstFree;             ///< first free FAT entry found 
+        TUint32 iCurrFreeEntries;       ///< current number of free FAT entries found by DoParseFatBuf()
+        TUint32 iCurrOccupiedEntries;   ///< current number of non-free FAT entries found by DoParseFatBuf()
+        };
+
+
+private:
+    CAtaFatTable(CFatMountCB& aOwner);
+
+    void RequestRawWriteAccess(TInt64 aPos, TUint32 aLen) const;
+    
+    void SetFreeClusters(TUint32 aFreeClusters);
+    void SetFreeClusterHint(TUint32 aCluster);
+    void CountFreeClustersL();
+    void CreateCacheL();
+    
+    virtual void DecrementFreeClusterCount(TUint32 aCount); 
+    virtual void IncrementFreeClusterCount(TUint32 aCount);
+    virtual TUint32 FindClosestFreeClusterL(TUint32 aCluster);
+
+    void DoCountFreeClustersL();
+    void DoParseFatBuf(const TPtrC8& aBuf, TFatScanParam& aScanParam) const;
+
+    TBool RequestFreeClusters(TUint32 aClustersRequired) const;
+    void DoLaunchFat32FreeSpaceScanThreadL();
+    void DestroyHelperThread();
+
+    inline TState State() const;
+    inline void SetState(TState aState);
+    
+private:
+
+    
+    CFatCacheBase*         iCache;         ///< FAT cache, fixed or LRU depending on the FAT type
+    TFatDriveInterface&    iDriveInteface; ///< reference to the drive interface
+    CFatHelperThreadBase*  ipHelperThread; ///< helper thread object pointer. NULL if it is not present
+    TState                 iState;         ///< state of this object 
+
+    //-- friends
+    friend TInt FAT32_ScanThread(TAny* apHostObject);
+    friend class CFat32ScanThread;
+    friend class CFat32FreeSpaceScanner;
+    friend class CFat32BitCachePopulator;
+    };
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+
+/**
+    Fat table abstraction for RAM media type.
+    Supports FAT16/32 only
+*/
+class CRamFatTable : public CFatTable
+    {
+public:
+    
+    static CRamFatTable* NewL(CFatMountCB& aOwner);
+    void InitializeL();
+    void MountL(const TMountParams& aMountParam);
+
+
+    TUint32 ReadL(TUint32 aFatIndex) const;
+    void WriteL(TUint32 aFatIndex, TUint32 aValue);
+    TInt64 DataPositionInBytes(TUint32 aCluster) const;
+    void FreeClusterListL(TUint32 aCluster);
+    TUint32 AllocateSingleClusterL(TUint32 aNearestCluster);
+    void ExtendClusterListL(TUint32 aNumber,TInt& aCluster);
+
+private:
+    CRamFatTable(CFatMountCB& aOwner);
+
+    inline TUint8 *RamDiskBase() const;
+    inline TInt AllocateClusterNumber();
+    inline void WriteFatTable(TInt aFatIndex,TInt aValue);
+    inline void WriteFatTable(TInt aFatIndex,TInt aFatValue,TInt anIndirectionTableValue);
+    inline void ReadIndirectionTable(TUint32& aCluster) const;
+    inline void WriteIndirectionTable(TInt aFatIndex,TInt aValue);
+    inline TUint8* MemCopy(TAny* aTrg,const TAny* aSrc,TInt aLength);
+    inline TUint8* MemCopyFillZ(TAny* aTrg, TAny* aSrc, TInt aLength);
+    inline void ZeroFillCluster(TInt aCluster);
+    
+    void UpdateIndirectionTable(TUint32 aStartCluster,TUint32 anEndCluster,TInt aNum);
+
+protected:
+
+    TInt iFatTablePos;          ///< Current position in the fat table
+    TInt iIndirectionTablePos;  ///< Current position in indirection table, second fat used for this
+    TUint8* iRamDiskBase;       ///< Pointer to the Ram disk base
+    };
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+
+/**
+    Abstract base class for the FAT32 helper threads.
+    Provides basic functionality of the helper threads and interface to the owher CAtaFatTable.
+*/
+class CFatHelperThreadBase : public CBase
+{
+ public: 
+    
+    /** Possible types of the FAT32 helper threads */
+    enum TFatHelperThreadType
+        {
+        EInvalidType,       ///< invalid type
+        EFreeSpaceScanner,  ///< Free FAT32 entries counter, see CFat32FreeSpaceScanner
+        EBitCachePopulator  ///< FAT32 bit supercache populating thread.
+        };
+    
+    /** this object states, mostly related to the worker thread activity and results */
+    enum TState
+        {
+        EInvalid,       ///< invalid initial state
+        ENotStarted,    ///< the worker thread hasn't started yet
+        EWorking,       ///< worker thread is working
+        EFinished_OK,   ///< worker thread has successfully finished, everything is fine.
+        EFailed         ///< worker thread failed to finish its job for some reason; see the thread completion status
+        };
+ 
+ public:
+    ~CFatHelperThreadBase();
+
+    //-- virtual interface
+    virtual TFatHelperThreadType Type() const = 0;
+    virtual TInt Launch()=0; 
+    virtual void RequestFatEntryWriteAccess(TUint32 aFatIndex) const=0;
+
+    //-- non-virtual interface for external user only
+    void Close();
+    void ForceStop(); 
+    
+    inline TState State() const;
+
+    inline void Suspend() const;
+    inline void Resume()  const;
+    
+    inline TInt  ThreadCompletionCode() const;
+    inline TBool ThreadWorking() const;
+    
+    inline void BoostPriority(TBool aBoost) const;
+    inline TBool IsPriorityBoosted() const;
+
+    inline TThreadId ThreadId() const;
+
+    TInt WaitToFinish() const;
+
+ protected:
+    CFatHelperThreadBase(CAtaFatTable& aOwner);
+     
+    //-- outlaws
+    CFatHelperThreadBase();
+    CFatHelperThreadBase(const CFatHelperThreadBase&);
+    CFatHelperThreadBase& operator=(const CFatHelperThreadBase&);
+
+    /** the worker thread priorities values */
+    enum 
+        {
+        EHelperPriorityNormal  = EPriorityMuchLess, ///< FAT32 Helper thread normal priority (assigned on start)
+        EHelperPriorityBoosted = EPriorityNormal    ///< FAT32 Helper thread bosted priority
+        };                                   
+
+    TInt DoLaunchThread(TThreadFunction aFunction, TAny* aThreadParameter);
+
+    inline void SetState(TState aState);
+    inline TBool AllowedToLive() const;
+    inline void  AllowToLive(TBool aAllow);
+
+ protected:
+    CAtaFatTable&           iOwner;         ///< owner, CAtaFatTable
+
+ private:
+    TState                  iState;         ///< internal state of this object
+    RThread                 iThread;        ///< FAT helper thread handle
+    mutable TRequestStatus  iThreadStatus;  ///< helper thread logon status
+    
+            TBool           iAllowedToLive   : 1;    ///< if EFalse the worker thread must gracefully finish ASAP.
+    mutable TBool           iPriorityBoosted : 1;    ///< ETrue when thread priority is boosted by BoostPriority() call
+
+
+};
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+/**
+    Abstract base class for the FAT32 helper threads that read FAT by big chunks of data and parse it.
+    Provides basic functionality of the helper threads and interface to the owher CAtaFatTable.
+*/
+class CFat32ScanThread : public CFatHelperThreadBase
+{
+ public:   
+
+    virtual TInt Launch();
+
+ protected:
+    CFat32ScanThread(CAtaFatTable& aOwner);
+    
+    //-- virtual private interface for the thread function.
+    virtual TInt Thread_Preamble();
+    virtual TInt Thread_Postamble(TInt aResult);
+    virtual TInt Thread_ProcessCollectedFreeEntries(const CAtaFatTable::TFatScanParam& aFatScanParam)=0;    
+
+    friend TInt FAT32_ScanThread(TAny* apHostObject); ///< FAT32 scanner thread function, generic functionality for derived classes
+
+ protected:
+     
+    RBuf8   iFatChunkBuf; ///< a buffer for reading FAT directly from the media
+
+    TTime   iTimeStart;   ///< thread start time, used to measure how long thread worked
+    TTime   iTimeEnd;     ///< thread end time, used to measure how long thread worked
+
+    CFatBitCache *ipFatBitCache; ///< interface to the FAT bit supercache (if it is present)
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+/**
+    FAT32 free FAT entries scanner thread.
+    Represents transient FAT32 helper thread that can be launched on FAT table object mounting stage and will be 
+    counting free FAT entries in order to find out free space on the volume.
+*/
+class CFat32FreeSpaceScanner : public CFat32ScanThread
+{
+ public:   
+
+    static CFat32FreeSpaceScanner* NewL(CAtaFatTable& aOwner);
+
+    virtual inline TFatHelperThreadType Type() const;
+
+ private:
+    CFat32FreeSpaceScanner(CAtaFatTable& aOwner);
+    
+    void RequestFatEntryWriteAccess(TUint32 aFatIndex) const;
+
+    //-- virtual private interface for the thread function.
+    TInt Thread_Preamble();
+    TInt Thread_Postamble(TInt aResult);
+    TInt Thread_ProcessCollectedFreeEntries(const CAtaFatTable::TFatScanParam& aFatScanParam);    
+    //--
+
+ private:
+    
+    void SetClustersScanned(TUint32 aClusters);
+    TUint32 ClustersScanned() const;
+    
+    friend TInt FAT32_ScanThread(TAny* apHostObject); ///< FAT32 scanner thread function, generic functionality for CFat32ScanThread derived classes
+
+ private:
+
+    enum 
+        {
+        KFatChunkBufSize_Small = 16*K1KiloByte, //-- buffer size for reading small FAT tables
+        KFatChunkBufSize_Big   = 64*K1KiloByte, //-- buffer size for reading large FAT tables
+        
+        KBigSzFat_Threshold    = 2*K1MegaByte,  //-- if FAT table size > this value, larger FAT read chunk (KFatChunkBufSize_Big) will be used
+        }; 
+
+    TUint32  iClustersScanned;  ///<  Number of FAT entries already scanned by the thread. Counts from the beginning of the FAT
+
+    //-- volume space treshold in bytes that causes CMountCB::SetDiskSpaceChange() to be called by FAT32 free space scanner thread.
+    //-- This thread will be calling CMountCB::SetDiskSpaceChange() after processing number of FAT32 entries corresponding to
+    //-- this amount of space in FAT clusters. e.g. after processing amount of FAT32 entries comprising 256MB volume space
+    enum {KVolSpaceNotifyThreshold = 256 * K1MegaByte}; 
+
+    TUint32 iEntriesNotifyThreshold; ///< the value of FAT32 entries need to be counted for CMountCB::SetDiskSpaceChange() call
+    TUint32 iNfyThresholdInc;        ///< Threshold increment in FAT32 entries. 
+
+    
+};
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+/**
+    FAT32 Bit supercache populating thread.
+    Represents transient FAT32 helper thread that is populating bit supercache in backgroud.
+*/
+class CFat32BitCachePopulator : public CFat32ScanThread
+{
+ public:   
+
+    static CFat32BitCachePopulator* NewL(CAtaFatTable& aOwner);
+
+    virtual inline TFatHelperThreadType Type() const;
+
+ private:
+    CFat32BitCachePopulator(CAtaFatTable& aOwner);
+    
+    void RequestFatEntryWriteAccess(TUint32 aFatIndex) const;
+
+    //-- virtual private interface for the thread function.
+    TInt Thread_Preamble();
+    TInt Thread_Postamble(TInt aResult);
+    TInt Thread_ProcessCollectedFreeEntries(const CAtaFatTable::TFatScanParam& aFatScanParam);    
+    //--
+
+ private:
+    friend TInt FAT32_ScanThread(TAny* apHostObject); ///< FAT32 scanner thread function, generic functionality for CFat32ScanThread derived classes
+    enum {KFatChunkBufSize = 16*K1KiloByte}; //-- buffer size for FAT reading 
+
+ private:
+    TUint32  iTotalOccupiedFatEntries; ///< total counted number of non-free FAT entries
+
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------------------
+
+#include "fat_table32.inl"
+
+#endif //FAT_TABLE_32_H
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+