reactos/drivers/filesystems/udfs/Include/wcache_lib.h
2021-06-11 15:33:08 +03:00

310 lines
11 KiB
C

////////////////////////////////////////////////////////////////////
// Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
// All rights reserved
// This file was released under the GPLv2 on June 2015.
////////////////////////////////////////////////////////////////////
#ifndef __CDRW_WCACHE_LIB_H__
#define __CDRW_WCACHE_LIB_H__
extern "C" {
#include "platform.h"
#ifdef _CONSOLE
#include "env_spec_w32.h"
#else
//#include "env_spec.h"
#endif
#define WCACHE_BOUND_CHECKS
typedef OSSTATUS (*PWRITE_BLOCK) (IN PVOID Context,
IN PVOID Buffer, // Target buffer
IN SIZE_T Length,
IN lba_t Lba,
OUT PSIZE_T WrittenBytes,
IN uint32 Flags);
typedef OSSTATUS (*PREAD_BLOCK) (IN PVOID Context,
IN PVOID Buffer, // Target buffer
IN SIZE_T Length,
IN lba_t Lba,
OUT PSIZE_T ReadBytes,
IN uint32 Flags);
typedef OSSTATUS (*PWRITE_BLOCK_ASYNC) (IN PVOID Context,
IN PVOID WContext,
IN PVOID Buffer, // Target buffer
IN SIZE_T Length,
IN lba_t Lba,
OUT PSIZE_T WrittenBytes,
IN BOOLEAN FreeBuffer);
typedef OSSTATUS (*PREAD_BLOCK_ASYNC) (IN PVOID Context,
IN PVOID WContext,
IN PVOID Buffer, // Source buffer
IN SIZE_T Length,
IN lba_t Lba,
OUT PSIZE_T ReadBytes);
/*typedef BOOLEAN (*PCHECK_BLOCK) (IN PVOID Context,
IN lba_t Lba);*/
#define WCACHE_BLOCK_USED 0x01
#define WCACHE_BLOCK_ZERO 0x02
#define WCACHE_BLOCK_BAD 0x04
typedef ULONG (*PCHECK_BLOCK) (IN PVOID Context,
IN lba_t Lba);
typedef OSSTATUS (*PUPDATE_RELOC) (IN PVOID Context,
IN lba_t Lba,
IN PULONG RelocTab,
IN ULONG BCount);
#define WCACHE_ERROR_READ 0x0001
#define WCACHE_ERROR_WRITE 0x0002
#define WCACHE_ERROR_INTERNAL 0x0003
#define WCACHE_W_OP FALSE
#define WCACHE_R_OP TRUE
typedef struct _WCACHE_ERROR_CONTEXT {
ULONG WCErrorCode;
OSSTATUS Status;
BOOLEAN Retry;
UCHAR Padding[3];
union {
struct {
ULONG Lba;
ULONG BCount;
PVOID Buffer;
} ReadWrite;
struct {
ULONG p1;
ULONG p2;
ULONG p3;
ULONG p4;
} Internal;
};
} WCACHE_ERROR_CONTEXT, *PWCACHE_ERROR_CONTEXT;
typedef OSSTATUS (*PWC_ERROR_HANDLER) (IN PVOID Context,
IN PWCACHE_ERROR_CONTEXT ErrorInfo);
// array of pointers to cached data
// each entry corresponds to logical block on disk
typedef struct _W_CACHE_ENTRY {
union {
PCHAR Sector;
UCHAR Flags:3;
};
} W_CACHE_ENTRY, *PW_CACHE_ENTRY;
// array of pointers to cache frames
// each frame corresponds to extent of logical blocks
typedef struct _W_CACHE_FRAME {
PW_CACHE_ENTRY Frame;
ULONG BlockCount;
//ULONG WriteCount; // number of modified packets in cache frame, is always 0, shall be removed
ULONG UpdateCount; // number of updates in cache frame
ULONG AccessCount; // number of accesses to cache frame
} W_CACHE_FRAME, *PW_CACHE_FRAME;
// memory type for cached blocks
#define CACHED_BLOCK_MEMORY_TYPE PagedPool
#define MAX_TRIES_FOR_NA 3
#define WCACHE_ADDR_MASK 0xfffffff8
#define WCACHE_FLAG_MASK 0x00000007
#define WCACHE_FLAG_MODIFIED 0x00000001
#define WCACHE_FLAG_ZERO 0x00000002
#define WCACHE_FLAG_BAD 0x00000004
#define WCACHE_MODE_ROM 0x00000000 // read only (CD-ROM)
#define WCACHE_MODE_RW 0x00000001 // rewritable (CD-RW)
#define WCACHE_MODE_R 0x00000002 // WORM (CD-R)
#define WCACHE_MODE_RAM 0x00000003 // random writable device (HDD)
#define WCACHE_MODE_EWR 0x00000004 // ERASE-cycle required (MO)
#define WCACHE_MODE_MAX WCACHE_MODE_RAM
#define PH_TMP_BUFFER 1
struct _W_CACHE_ASYNC;
typedef struct _W_CACHE {
// cache tables
ULONG Tag;
PW_CACHE_FRAME FrameList; // pointer to list of Frames
lba_t* CachedBlocksList; // sorted list of cached blocks
lba_t* CachedFramesList; // sorted list of cached frames
lba_t* CachedModifiedBlocksList; // sorted list of cached modified blocks
// settings & current state
ULONG BlocksPerFrame;
ULONG BlocksPerFrameSh;
ULONG BlockCount;
ULONG MaxBlocks;
ULONG MaxBytesToRead;
ULONG FrameCount;
ULONG MaxFrames;
ULONG PacketSize; // number of blocks in packet
ULONG PacketSizeSh;
ULONG BlockSize;
ULONG BlockSizeSh;
ULONG WriteCount; // number of modified packets in cache
lba_t FirstLba;
lba_t LastLba;
ULONG Mode; // RO/WOR/RW/EWR
ULONG Flags;
BOOLEAN CacheWholePacket;
BOOLEAN DoNotCompare;
BOOLEAN Chained;
BOOLEAN RememberBB;
BOOLEAN NoWriteBB;
BOOLEAN NoWriteThrough;
UCHAR Padding[2];
ULONG RBalance;
ULONG WBalance;
ULONG FramesToKeepFree;
// callbacks
PWRITE_BLOCK WriteProc;
PREAD_BLOCK ReadProc;
PWRITE_BLOCK_ASYNC WriteProcAsync;
PREAD_BLOCK_ASYNC ReadProcAsync;
PCHECK_BLOCK CheckUsedProc;
PUPDATE_RELOC UpdateRelocProc;
PWC_ERROR_HANDLER ErrorHandlerProc;
// sync resource
ERESOURCE WCacheLock;
// BOOLEAN WCResInit;
// preallocated tmp buffers
PCHAR tmp_buff;
PCHAR tmp_buff_r;
PULONG reloc_tab;
} W_CACHE, *PW_CACHE;
#define WCACHE_INVALID_LBA ((lba_t)(-1))
#define WCACHE_CACHE_WHOLE_PACKET 0x01
#define WCACHE_DO_NOT_COMPARE 0x02
#define WCACHE_CHAINED_IO 0x04
#define WCACHE_MARK_BAD_BLOCKS 0x08
#define WCACHE_RO_BAD_BLOCKS 0x10
#define WCACHE_NO_WRITE_THROUGH 0x20
#define WCACHE_VALID_FLAGS (WCACHE_CACHE_WHOLE_PACKET | \
WCACHE_DO_NOT_COMPARE | \
WCACHE_CHAINED_IO | \
WCACHE_MARK_BAD_BLOCKS | \
WCACHE_RO_BAD_BLOCKS | \
WCACHE_NO_WRITE_THROUGH)
#define WCACHE_INVALID_FLAGS (0xffffffff)
// init cache
OSSTATUS WCacheInit__(IN PW_CACHE Cache,
IN ULONG MaxFrames,
IN ULONG MaxBlocks,
IN SIZE_T MaxBytesToRead,
IN ULONG PacketSizeSh, // number of blocks in packet (bit shift)
IN ULONG BlockSizeSh, // bit shift
IN ULONG BlocksPerFrameSh,// bit shift
IN lba_t FirstLba,
IN lba_t LastLba,
IN ULONG Mode,
IN ULONG Flags,
IN ULONG FramesToKeepFree,
IN PWRITE_BLOCK WriteProc,
IN PREAD_BLOCK ReadProc,
IN PWRITE_BLOCK_ASYNC WriteProcAsync,
IN PREAD_BLOCK_ASYNC ReadProcAsync,
IN PCHECK_BLOCK CheckUsedProc,
IN PUPDATE_RELOC UpdateRelocProc,
IN PWC_ERROR_HANDLER ErrorHandlerProc);
// write cached
OSSTATUS WCacheWriteBlocks__(IN PW_CACHE Cache,
IN PVOID Context,
IN PCHAR Buffer,
IN lba_t Lba,
IN ULONG BCount,
OUT PSIZE_T WrittenBytes,
IN BOOLEAN CachedOnly);
// read cached
OSSTATUS WCacheReadBlocks__(IN PW_CACHE Cache,
IN PVOID Context,
IN PCHAR Buffer,
IN lba_t Lba,
IN ULONG BCount,
OUT PSIZE_T ReadBytes,
IN BOOLEAN CachedOnly);
// flush blocks
OSSTATUS WCacheFlushBlocks__(IN PW_CACHE Cache,
IN PVOID Context,
IN lba_t Lba,
IN ULONG BCount);
// discard blocks
VOID WCacheDiscardBlocks__(IN PW_CACHE Cache,
IN PVOID Context,
IN lba_t Lba,
IN ULONG BCount);
// flush whole cache
VOID WCacheFlushAll__(IN PW_CACHE Cache,
IN PVOID Context);
// purge whole cache
VOID WCachePurgeAll__(IN PW_CACHE Cache,
IN PVOID Context);
// free structures
VOID WCacheRelease__(IN PW_CACHE Cache);
// check if initialized
BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache);
// direct access to cached data
OSSTATUS WCacheDirect__(IN PW_CACHE Cache,
IN PVOID Context,
IN lba_t Lba,
IN BOOLEAN Modified,
OUT PCHAR* CachedBlock,
IN BOOLEAN CachedOnly);
// release resources after direct access
OSSTATUS WCacheEODirect__(IN PW_CACHE Cache,
IN PVOID Context);
// release resources before direct access
OSSTATUS WCacheStartDirect__(IN PW_CACHE Cache,
IN PVOID Context,
IN BOOLEAN Exclusive);
// check if requested extent completly cached
BOOLEAN WCacheIsCached__(IN PW_CACHE Cache,
IN lba_t Lba,
IN ULONG BCount);
// change cache media mode
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache,
IN ULONG Mode);
//
ULONG WCacheGetMode__(IN PW_CACHE Cache);
//
ULONG WCacheGetWriteBlockCount__(IN PW_CACHE Cache);
//
VOID WCacheSyncReloc__(IN PW_CACHE Cache,
IN PVOID Context);
VOID WCacheDiscardBlocks__(IN PW_CACHE Cache,
IN PVOID Context,
IN lba_t ReqLba,
IN ULONG BCount);
ULONG WCacheChFlags__(IN PW_CACHE Cache,
IN ULONG SetFlags,
IN ULONG ClrFlags);
};
// complete async request (callback)
OSSTATUS WCacheCompleteAsync__(IN PVOID WContext,
IN OSSTATUS Status);
#endif // __CDRW_WCACHE_LIB_H__