/* * BlockCache.hpp * Per-mount LRU cache of filesystem blocks * Copyright (c) 2026 Daniel Hammer */ #pragma once #include namespace Fs::BlockCache { // A cache over one partition of a block device, in units of the // filesystem's block size (512..4096 bytes, addressed in 512-byte sectors // from the partition start). Write-through: Write reaches the device // before it returns, so the cache never holds dirty data and there is // nothing to flush on sync or unmount. // // Not internally locked. Callers serialize access; the VFS already holds // vfsLock across every driver call. struct Cache; // Create a cache for the partition. Capacity is sized from free memory at // the time of the call; block pages are allocated lazily as the cache // fills and returned on Destroy. Returns nullptr if the bookkeeping // cannot be allocated (callers then do uncached I/O). Cache* Create(int blockDevIndex, uint64_t partStartLba, uint32_t blockSize); void Destroy(Cache* cache); // Read one block, from the cache or the device. Block 0 is never cached. bool Read(Cache* cache, uint32_t block, void* buf); // Write one block to the device, then update the cached copy. bool Write(Cache* cache, uint32_t block, const void* buf); bool Contains(Cache* cache, uint32_t block); // Pull `count` physically contiguous blocks starting at `first` into the // cache, in as few device commands as possible. Blocks already cached are // skipped. Best effort: a failed read just leaves those blocks uncached. void Prefetch(Cache* cache, uint32_t first, uint32_t count); // Largest run Prefetch reads in one device command. uint32_t MaxRunBlocks(Cache* cache); };