diff --git a/src/fs.c b/src/fs.c index 6c886dd..ed86000 100644 --- a/src/fs.c +++ b/src/fs.c @@ -1254,7 +1254,7 @@ int fs_truncate(void *d) // look through base inode blocks for (int i = 0; i < BLOCK_ADDRESSES_PER_INODE; i++, blocks_seen++) { - if ((blocks_seen > new_block_amount) && (f.blocks[i])) { + if ((blocks_seen >= new_block_amount) && (f.blocks[i])) { mark_free(f.blocks[i]); f.blocks[i] = 0; } @@ -1270,7 +1270,7 @@ int fs_truncate(void *d) read_block(next_ext, (void *) &ext); for (int i = 0; i < BLOCK_ADDRESSES_PER_INODE_EXTENSION; i++, blocks_seen++) { - if ((blocks_seen > new_block_amount) && (ext.blocks[i])) { + if ((blocks_seen >= new_block_amount) && (ext.blocks[i])) { mark_free(ext.blocks[i]); ext.blocks[i] = 0; } @@ -1281,7 +1281,11 @@ int fs_truncate(void *d) } // look through inode extensions themselves - int required_extensions = (f.size - BLOCK_ADDRESSES_PER_INODE) / BLOCK_ADDRESSES_PER_INODE_EXTENSION; + int required_blocks_after_base_inode = (int) f.size - (int) BLOCK_ADDRESSES_PER_INODE; + int required_extensions = required_blocks_after_base_inode >= 0 + ? required_blocks_after_base_inode / BLOCK_ADDRESSES_PER_INODE_EXTENSION + : 0; + if ((f.size - BLOCK_ADDRESSES_PER_INODE) % BLOCK_ADDRESSES_PER_INODE_EXTENSION) required_extensions++; @@ -1291,23 +1295,23 @@ int fs_truncate(void *d) // zero base inode next_extension ptr f.next_extension = 0; write_block(read_inode_ptr(file_inode_ptr), (void *) &f); + } else { + // seek to last required extension + for (int i = 0; i < required_extensions; i++) { + if (!next_ext) + return 0; + + curr_ext = next_ext; + read_block(curr_ext, (void *) &ext); + next_ext = ext.next_extension; + } + + // remove next_extension ptr + ext.next_extension = 0; + write_block(curr_ext, (void *) &ext); } - // seek to last required extension - for (int i = 0; i < required_extensions; i++) { - if (!next_ext) - return 0; - - curr_ext = next_ext; - read_block(next_ext, (void *) &ext); - next_ext = ext.next_extension; - } - - // remove next_extension ptr - ext.next_extension = 0; - write_block(curr_ext, (void *) &ext); - - // erase all extensions after this one + // erase all remaining extensions while (next_ext) { mark_free(next_ext); read_block(next_ext, (void *) &ext);