#ifndef FILESYSTEM_H_5 #define FILESYSTEM_H_5 #ifdef _WIN32 #include #endif #include #include "../Interface/Types.h" #include "../Interface/File.h" #include "IFilesystem.h" #include "IFSImageFactory.h" #include #include #include class VHDFile; class Filesystem_ReadaheadThread; class Filesystem; enum ENextBlockState { ENextBlockState_Queued, ENextBlockState_Ready, ENextBlockState_Error }; const size_t fs_readahead_n_max_buffers=64; struct SNextBlock; class SBlockBuffer : public IFilesystem::IFsBuffer { public: virtual char* getBuf() { return buffer; } char* buffer; SNextBlock* block; ENextBlockState state; }; struct SNextBlock { SBlockBuffer buffers[fs_readahead_n_max_buffers]; size_t n_buffers; Filesystem* fs; #ifdef _WIN32 OVERLAPPED ovl; #endif }; class Filesystem : public IFilesystem, public IFsNextBlockCallback { public: Filesystem(const std::string &pDev, IFSImageFactory::EReadaheadMode read_ahead, IFsNextBlockCallback* next_block_callback); Filesystem(IFile *pDev, IFsNextBlockCallback* next_block_callback); virtual ~Filesystem(); virtual int64 getBlocksize(void)=0; virtual int64 getSize(void)=0; virtual const unsigned char *getBitmap(void)=0; virtual bool hasBlock(int64 pBlock); virtual IFsBuffer* readBlock(int64 pBlock, bool* p_has_error=NULL); std::vector readBlocks(int64 pStartBlock, unsigned int n, const std::vector& buffers, unsigned int buffer_offset); bool hasError(void); int64 calculateUsedSpace(void); virtual void releaseBuffer(IFsBuffer* buf); virtual void shutdownReadahead(); virtual IFsBuffer* readBlockInt(int64 pBlock, bool use_readahead, bool* p_has_error); int64 nextBlockInt(int64 curr_block); #ifdef _WIN32 void overlappedIoCompletion(SNextBlock* block, DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, int64 offset); #endif virtual int64 nextBlock(int64 curr_block); virtual void slowReadWarning(int64 passed_time_ms, int64 curr_block); virtual void waitingForBlockCallback(int64 curr_block); virtual int64 getOsErrorCode(); void readaheadSetMaxNBuffers(int64 n_max_buffers); bool excludeFiles(const std::string& path, const std::string& fn_contains); bool excludeFile(const std::string& path); bool excludeSectors(int64 start, int64 count); bool excludeBlock(int64 block); protected: bool readFromDev(char *buf, _u32 bsize); void initReadahead(IFSImageFactory::EReadaheadMode read_ahead, bool background_priority); bool queueOverlappedReads(bool force_queue); bool waitForCompletion(unsigned int wtimems); size_t usedNextBlocks(); IFile *dev; void completionFreeBuffer(SBlockBuffer* block_buf); SBlockBuffer* completionGetBlock(int64 pBlock, bool* p_has_error); bool has_error; int64 errcode; bool own_dev; class SSimpleBuffer : public IFsBuffer { public: char* buf; virtual char* getBuf() { return buf; } }; IFsBuffer* getBuffer(); std::vector buffers; std::unique_ptr buffer_mutex; std::unique_ptr readahead_thread; THREADPOOL_TICKET readahead_thread_ticket; size_t num_uncompleted_blocks; int64 overlapped_next_block; std::vector next_blocks; std::map queued_next_blocks; std::stack free_next_blocks; IFsNextBlockCallback* next_block_callback; IFSImageFactory::EReadaheadMode read_ahead_mode; int64 curr_fs_readahead_n_max_buffers; #ifdef _WIN32 HANDLE hVol; #endif }; #endif //FILESYSTEM_H_5