diff options
author | Anton Kling <anton@kling.gg> | 2023-10-28 21:42:09 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-30 21:49:48 +0100 |
commit | 4c2e0016a2fdfaccf04431ea7205c09dc73c57f8 (patch) | |
tree | cf20013ccfe66074e567aa2f695a1787ed9d73b4 | |
parent | d50d18c9da3a125f0196bec89802dec1c5b0b800 (diff) |
EXT2: Improve block cache
This significantly speeds up certain operations as indirect block
looksup now don't need to make as many requests to the hard drive.
-rw-r--r-- | fs/ext2.c | 55 |
1 files changed, 42 insertions, 13 deletions
@@ -23,25 +23,54 @@ void ext2_close(vfs_fd_t *fd) { int read_inode(int inode_num, unsigned char *data, uint64_t size, uint64_t offset, uint64_t *file_size); -uint32_t old_block_num = -1; -uint8_t old_block[1024]; // FIXME: Not always 1024 +struct BLOCK_CACHE { + uint32_t block_num; + uint8_t block[1024]; +}; + +#define NUM_BLOCK_CACHE 30 +struct BLOCK_CACHE cache[NUM_BLOCK_CACHE] = {0}; +uint8_t last_taken_cache = 0; + +void cached_read_block(uint32_t block, void *address, size_t size, + size_t offset) { + int free_found = -1; + for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + if (cache[i].block_num == block) { + memcpy(address, cache[i].block + offset, size); + return; + } + if (0 == cache[i].block_num) + free_found = i; + } + + if (-1 == free_found) { + free_found = last_taken_cache; + last_taken_cache++; + if (last_taken_cache >= NUM_BLOCK_CACHE) + last_taken_cache = 0; + } + + struct BLOCK_CACHE *c = &cache[free_found]; + c->block_num = block; + read_lba(block * block_byte_size / 512, c->block, 1024, 0); + return cached_read_block(block, address, size, offset); +} + void ext2_read_block(uint32_t block, void *address, size_t size, size_t offset) { - // Very simple cache, it you are reading the same block then don't - // bother trying to read from the hard drive again, juse use the old - // data. - if (block == old_block_num) { - memcpy(address, old_block + offset, size); - return; - } - read_lba(block * block_byte_size / 512, address, size, offset); - read_lba(block * block_byte_size / 512, old_block, 1024, 0); - old_block_num = block; + cached_read_block(block, address, size, offset); } void ext2_write_block(uint32_t block, void *address, size_t size, size_t offset) { - old_block_num = -1; // Invalidate the old block cache + // Invalidate a old cache + for (int i = 0; i < NUM_BLOCK_CACHE; i++) { + if (cache[i].block_num == block) { + cache[i].block_num = 0; + break; + } + } write_lba(block * block_byte_size / 512, address, size, offset); } |