summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-06-29 14:28:24 +0200
committerAnton Kling <anton@kling.gg>2024-06-30 13:19:15 +0200
commit8c8183cd3a6eef42f215e422ef29b77990d75b20 (patch)
tree14405adec57062382bbee97d0487edf5bf721d4b
parenta30f0e8316a8da4c53d9fd5f40fa2abeb6fc0e47 (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.
-rw-r--r--kernel/fs/ext2.c27
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);