Ah, I see now why this patch is needed. If we don't update the block allocation bitmap to indicate block has been taken, and there is a need to allocate an htree index block, we will end up allocating the same block twice. Thanks, I've applied this patch with the following added. - Ted diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c index 947003eb..437c8ffc 100644 --- a/lib/ext2fs/mkdir.c +++ b/lib/ext2fs/mkdir.c @@ -43,6 +43,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, blk64_t blk; char *block = 0; int inline_data = 0; + int drop_refcount = 0; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -149,6 +150,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, if (!inline_data) ext2fs_block_alloc_stats2(fs, blk, +1); ext2fs_inode_alloc_stats2(fs, ino, +1, 1); + drop_refcount = 1; /* * Link the directory into the filesystem hierarchy @@ -181,10 +183,16 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, if (retval) goto cleanup; } + drop_refcount = 0; cleanup: if (block) ext2fs_free_mem(&block); + if (drop_refcount) { + if (!inline_data) + ext2fs_block_alloc_stats2(fs, blk, -1); + ext2fs_inode_alloc_stats2(fs, ino, -1, 1); + } return retval; } diff --git a/lib/ext2fs/symlink.c b/lib/ext2fs/symlink.c index 3e07a539..a66fb7ec 100644 --- a/lib/ext2fs/symlink.c +++ b/lib/ext2fs/symlink.c @@ -54,6 +54,7 @@ errcode_t ext2fs_symlink(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t ino, int fastlink, inlinelink; unsigned int target_len; char *block_buf = 0; + int drop_refcount = 0; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -168,6 +169,7 @@ need_block: if (!fastlink && !inlinelink) ext2fs_block_alloc_stats2(fs, blk, +1); ext2fs_inode_alloc_stats2(fs, ino, +1, 0); + drop_refcount = 1; /* * Link the symlink into the filesystem hierarchy @@ -185,10 +187,16 @@ need_block: if (retval) goto cleanup; } + drop_refcount = 0; cleanup: if (block_buf) ext2fs_free_mem(&block_buf); + if (drop_refcount) { + if (!fastlink && !inlinelink) + ext2fs_block_alloc_stats2(fs, blk, -1); + ext2fs_inode_alloc_stats2(fs, ino, -1, 0); + } return retval; }