diff --git a/src/fs.c b/src/fs.c index 02adcaa..f92fcdd 100644 --- a/src/fs.c +++ b/src/fs.c @@ -107,7 +107,7 @@ static void mark_free(unsigned int block_no) read_block(0, (void *) &fsh); if (block_no > fsh.block_count) { - pr_err("block %d is out of fimesystem block range (%d)\n", block_no, fsh.block_count); + pr_err("block %d is out of filesystem block range (%d)\n", block_no, fsh.block_count); return; } @@ -922,6 +922,7 @@ static int write_fd_block(unsigned int fd, unsigned int block_index, unsigned ch struct fs_inode_extension ext; memset(&ext, 0, sizeof(struct fs_inode_extension)); + write_block(new_block, (void *) &ext); f.next_extension = new_block; write_block(fs_file_descriptions[fd].inode, (void *) &f); @@ -1104,25 +1105,40 @@ int fs_write(void *d) int block_index = fs_file_descriptions[fd].rw_offset / FS_BLOCK_SIZE; int block_offset = fs_file_descriptions[fd].rw_offset % FS_BLOCK_SIZE; + unsigned int total_bytes_written = 0; + unsigned char data_buffer[FS_BLOCK_SIZE]; - if (block_offset + str_len <= FS_BLOCK_SIZE) { + // first block + read_fd_block(fd, block_index, data_buffer); + { + unsigned int copy_amount = ((FS_BLOCK_SIZE - block_offset) <= str_len) + ? FS_BLOCK_SIZE - block_offset + : str_len; + memcpy(&(data_buffer[block_offset]), str, copy_amount); + total_bytes_written += copy_amount; + } + write_fd_block(fd, block_index, data_buffer); + block_index++; + + // full middle blocks + for ( ; str_len - total_bytes_written >= FS_BLOCK_SIZE; block_index++) { + write_fd_block(fd, block_index, (unsigned char *) &(str[total_bytes_written])); + total_bytes_written += FS_BLOCK_SIZE; + } + + // last partial block + if (str_len - total_bytes_written) { read_fd_block(fd, block_index, data_buffer); - memcpy(&(data_buffer[block_offset]), str, str_len); - write_fd_block(fd, block_index, data_buffer); - } else { - read_fd_block(fd, block_index, data_buffer); - memcpy(&(data_buffer[block_offset]), str, FS_BLOCK_SIZE - block_offset); + memcpy(data_buffer, &(str[total_bytes_written]), str_len - total_bytes_written); write_fd_block(fd, block_index, data_buffer); - read_fd_block(fd, block_index+1, data_buffer); - memcpy(data_buffer, &(str[FS_BLOCK_SIZE - block_offset]), str_len - block_offset); - write_fd_block(fd, block_index+1, data_buffer); + total_bytes_written += (str_len - total_bytes_written); } pr("Moving fd %d offset: %d -> %d\n", - fd, fs_file_descriptions[fd].rw_offset, fs_file_descriptions[fd].rw_offset + str_len); - fs_file_descriptions[fd].rw_offset += str_len; + fd, fs_file_descriptions[fd].rw_offset, fs_file_descriptions[fd].rw_offset + total_bytes_written); + fs_file_descriptions[fd].rw_offset += total_bytes_written; struct fs_inode f; read_block(fs_file_descriptions[fd].inode, (void *) &f);