Files
nt-lite/code/drivers/fs/fat/fat_internal.h
T

154 lines
6.1 KiB
C

// FAT private implementation model shared by the driver's translation units.
#pragma once
#include <stdbool.h>
#include "fat.h"
#include "fat_disk.h"
#define FAT_PATH_CACHE_SLOTS 64u
#define FAT_PATH_CACHE_MAX 512u
#define FAT_CHAIN_CACHE_SLOTS 16u
#define FAT_WRITE_RUN_MAX_SECTORS 128u
#define FAT_READ_RUN_MAX_SECTORS 512u
#define FAT_MAX_LFN 256
#ifndef FAT_DEBUG
#define FAT_DEBUG 0
#endif
#define FatDebugPrint(...) do { if (FAT_DEBUG) DbgPrint(__VA_ARGS__); } while (0)
typedef struct FAT_PATH_CACHE_ENTRY {
bool Valid;
uint64_t Generation;
uint32_t Hash;
size_t PathLength;
char Path[FAT_PATH_CACHE_MAX];
uint32_t Cluster;
uint32_t Size;
uint8_t Attr;
uint64_t DirentLba;
uint32_t DirentOffset;
} FAT_PATH_CACHE_ENTRY;
typedef struct FAT_CHAIN_CACHE_ENTRY {
bool Valid;
uint32_t LogicalStart;
uint32_t PhysicalStart;
uint32_t Length;
uint32_t NextCluster;
} FAT_CHAIN_CACHE_ENTRY;
struct FAT_VOL_S {
FAT_VARIANT Variant;
uint8_t DriveIndex;
uint64_t PartitionLba;
uint64_t PartitionSize;
uint32_t BytesPerSector;
uint32_t SectorsPerCluster;
uint32_t BytesPerCluster;
uint32_t ReservedSectors;
uint32_t NumFats;
uint32_t FatSize;
uint32_t RootCluster;
uint32_t RootEntryCount;
uint32_t RootDirSectors;
uint64_t RootDirStart;
uint64_t DataStart;
uint32_t TotalClusters;
uint32_t NextFreeHint;
SPINLOCK PathCacheLock;
uint64_t PathCacheGeneration;
IO_FILESYSTEM_STATS Stats;
FAT_PATH_CACHE_ENTRY PathCache[FAT_PATH_CACHE_SLOTS];
IO_VOLUME* Volume;
LIST_ENTRY MountLink;
};
typedef struct FAT_FILE {
uint32_t StartCluster;
uint32_t FileSize;
FAT_VOL* Vol;
uint64_t DirentLba;
uint32_t DirentOffset;
SPINLOCK ChainCacheLock;
uint32_t ChainCacheClock;
FAT_CHAIN_CACHE_ENTRY ChainCache[FAT_CHAIN_CACHE_SLOTS];
} FAT_FILE;
typedef struct FAT_ENCODED_TIME {
uint16_t Date;
uint16_t Time;
uint8_t CreateTimeTenth;
} FAT_ENCODED_TIME;
typedef struct FAT_DIRENT_UPDATE {
uint32_t Flags;
uint32_t Size;
uint32_t FirstCluster;
FAT_ENCODED_TIME Timestamp;
} FAT_DIRENT_UPDATE;
#define FAT_DIRENT_UPDATE_SIZE 0x00000001u
#define FAT_DIRENT_UPDATE_FIRST_CLUSTER 0x00000002u
#define FAT_DIRENT_UPDATE_CREATE_TIME 0x00000004u
#define FAT_DIRENT_UPDATE_WRITE_TIME 0x00000008u
#define FAT_DIRENT_UPDATE_ACCESS_DATE 0x00000010u
KSTATUS FatReadSectors(FAT_VOL* volume, uint64_t lba, uint32_t count, void* buffer);
KSTATUS FatWriteSectors(FAT_VOL* volume, uint64_t lba, uint32_t count, const void* buffer);
const char* FatVariantName(FAT_VARIANT variant);
uint32_t FatEocMark(FAT_VOL* volume);
bool FatIsDataCluster(FAT_VOL* volume, uint32_t cluster);
uint32_t FatDirentFirstCluster(FAT_VOL* volume, const DIRENT* dirent);
void FatSetDirentFirstCluster(FAT_VOL* volume, DIRENT* dirent, uint32_t cluster);
bool FatIsFixedRoot(FAT_VOL* volume, uint32_t dirCluster);
bool FatDirectoryFirstSegment(FAT_VOL* volume, uint32_t dirCluster,
uint32_t* cursorOut, uint64_t* lbaOut, uint32_t* sectorsOut);
bool FatDirectoryNextSegment(FAT_VOL* volume, uint32_t dirCluster,
uint32_t* cursorInOut, uint64_t* lbaOut, uint32_t* sectorsOut);
uint64_t FatClusterToLba(FAT_VOL* volume, uint32_t cluster);
uint32_t FatEntry(FAT_VOL* volume, uint32_t cluster);
KSTATUS FatWriteEntry(FAT_VOL* volume, uint32_t cluster, uint32_t value);
void FatFlushCache(FAT_VOL* volume);
uint32_t FatAllocClusterEx(FAT_VOL* volume, bool zeroCluster);
uint32_t FatAllocCluster(FAT_VOL* volume);
uint32_t FatAppendClusterEx(FAT_VOL* volume, uint32_t lastCluster, bool zeroCluster);
uint32_t FatAppendCluster(FAT_VOL* volume, uint32_t lastCluster);
uint32_t FatGetChainEnd(FAT_VOL* volume, uint32_t start, uint32_t* countOut);
void FatFreeClusterChain(FAT_VOL* volume, uint32_t start);
void FatQueryEncodedTime(FAT_ENCODED_TIME* out);
void FatDecodeDateTime(uint16_t date, uint16_t time, uint8_t createTenth, SYS_SYSTEM_TIME* out);
void FatDecodeAccessDate(uint16_t date, SYS_SYSTEM_TIME* out);
KSTATUS FatDirentUpdateMetadata(FAT_VOL* volume, uint64_t lba, uint32_t offset,
const FAT_DIRENT_UPDATE* update);
KSTATUS FatDirentUpdateSize(FAT_VOL* volume, uint64_t lba, uint32_t offset, uint32_t size);
KSTATUS FatDirentUpdateFirstCluster(FAT_VOL* volume, uint64_t lba, uint32_t offset, uint32_t cluster);
void FatLfnAppend(char* lfn, const LFN_ENTRY* entry);
void FatPathCacheInvalidate(FAT_VOL* volume);
void FatStatsAddReadRun(FAT_VOL* volume, uint32_t sectors, uint32_t merges);
void FatFileInitChainCache(FAT_FILE* file);
void FatFileInvalidateChainCache(FAT_FILE* file);
uint32_t FatResolveFileCluster(FAT_FILE* file, uint32_t logicalIndex);
bool FatBuildReadRun(FAT_FILE* file, uint32_t logicalIndex,
uint32_t startCluster, uint32_t maxSectors,
uint32_t* runSectorsOut, uint32_t* nextClusterOut);
KSTATUS FatLookupPathV(FAT_VOL* volume, SYS_STRING_VIEW path,
uint32_t* clusterOut, uint32_t* sizeOut, uint8_t* attrOut,
uint64_t* direntLbaOut, uint32_t* direntOffsetOut);
KSTATUS FatTraverseV(FAT_VOL* volume, SYS_STRING_VIEW path,
uint32_t* clusterOut, uint32_t* sizeOut);
KSTATUS FatResolveParentForMutation(FAT_VOL* volume, SYS_STRING_VIEW path,
uint32_t* parentClusterOut, SYS_STRING_VIEW* nameOut);
KSTATUS FatCreateDirent(FAT_VOL* volume, SYS_STRING_VIEW path,
uint8_t attr, uint32_t firstCluster, uint32_t size,
uint64_t* direntLbaOut, uint32_t* direntOffsetOut);
KSTATUS FatInitializeDirectoryCluster(FAT_VOL* volume, uint32_t dirCluster,
uint32_t parentCluster);
KSTATUS FatDirectoryIsEmpty(FAT_VOL* volume, uint32_t dirCluster, bool* emptyOut);
KSTATUS FatDeleteDirentRunV(FAT_VOL* volume, uint32_t parentCluster,
SYS_STRING_VIEW name);
void FatCacheInvalidate(void);
void FatCacheInvalidateVolume(FAT_VOL* volume);