46 lines
1.7 KiB
C++
46 lines
1.7 KiB
C++
/*
|
|
* BlockCache.hpp
|
|
* Per-mount LRU cache of filesystem blocks
|
|
* Copyright (c) 2026 Daniel Hammer
|
|
*/
|
|
|
|
#pragma once
|
|
#include <cstdint>
|
|
|
|
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);
|
|
|
|
};
|