diff options
author | Anton Kling <anton@kling.gg> | 2024-06-29 14:28:24 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-06-30 13:19:15 +0200 |
commit | 8c8183cd3a6eef42f215e422ef29b77990d75b20 (patch) | |
tree | 14405adec57062382bbee97d0487edf5bf721d4b /kernel/fs | |
parent | a30f0e8316a8da4c53d9fd5f40fa2abeb6fc0e47 (diff) |
ext2: Performance improvements to block write
Don't invalidate the cache of a block if written to. Instead the cache
can be changed and then be written to disk. This is optimal for ext2
since it gets to keep the cache and the hard drive since it may not have
to do extra reads when doing writes.
Diffstat (limited to 'kernel/fs')
-rw-r--r-- | kernel/fs/ext2.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index f2e7ba7..04108f4 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -78,20 +78,27 @@ void ext2_read_block(u32 block, void *address, size_t size, size_t offset) { cached_read_block(block, address, size, offset); } -void ext2_write_block(u32 block, void *address, size_t size, size_t offset) { - // Invalidate a old cache +void ext2_write_block(u32 block, u8 *address, size_t size, size_t offset) { + assert(offset + size <= block_byte_size); + int cache_index = -1; for (int i = 0; i < NUM_BLOCK_CACHE; i++) { if (cache[i].block_num == block) { - cache[i].block_num = 0; + cache_index = i; break; } } + if (-1 != cache_index) { + memcpy(cache[cache_index].block + offset, address, size); + raw_vfs_pwrite(mount_fd, cache[cache_index].block, block_byte_size, + block * block_byte_size); + return; + } raw_vfs_pwrite(mount_fd, address, size, block * block_byte_size + offset); } void write_group_descriptor(u32 group_index, bgdt_t *block_group) { int starting_block = (1024 == block_byte_size) ? 2 : 1; - ext2_write_block(starting_block, block_group, sizeof(bgdt_t), + ext2_write_block(starting_block, (u8 *)block_group, sizeof(bgdt_t), group_index * sizeof(bgdt_t)); } @@ -418,10 +425,8 @@ int get_free_inode(int allocate) { void write_to_indirect_block(u32 indirect_block, u32 index, u32 new_block) { index %= INDIRECT_BLOCK_CAPACITY; - u32 buffer[INDIRECT_BLOCK_CAPACITY]; - ext2_read_block(indirect_block, buffer, sizeof(buffer), 0); - buffer[index] = new_block; - ext2_write_block(indirect_block, buffer, sizeof(buffer), 0); + ext2_write_block(indirect_block, (u8 *)&new_block, sizeof(u32), + index * sizeof(u32)); } int ext2_allocate_block(inode_t *inode, u32 index) { @@ -455,8 +460,7 @@ int ext2_allocate_block(inode_t *inode, u32 index) { inode->double_indirect_block_pointer = n; } - u32 value = get_singly_block_index(inode->double_indirect_block_pointer, - index / INDIRECT_BLOCK_CAPACITY); + u32 value; if (0 == (index % INDIRECT_BLOCK_CAPACITY)) { int n = get_free_block(1 /*true*/); if (-1 == n) { @@ -465,6 +469,9 @@ int ext2_allocate_block(inode_t *inode, u32 index) { write_to_indirect_block(inode->double_indirect_block_pointer, index / INDIRECT_BLOCK_CAPACITY, n); value = n; + } else { + value = get_singly_block_index(inode->double_indirect_block_pointer, + index / INDIRECT_BLOCK_CAPACITY); } write_to_indirect_block(value, index, b); |