Index: uspace/lib/ext4/libext4_balloc.c
===================================================================
--- uspace/lib/ext4/libext4_balloc.c	(revision 81092ce09ffeee54114d8c0a2ddfffc2cfeda3e3)
+++ uspace/lib/ext4/libext4_balloc.c	(revision 662bd71c6b5b4811d54aad7632d9f3ddc5022357)
@@ -123,5 +123,5 @@
 	// Update superblock free blocks count
 	uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
-	sb_free_blocks--;
+	sb_free_blocks++;
 	ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
 
@@ -136,4 +136,82 @@
 			bg_ref->block_group, sb);
 	free_blocks++;
+	ext4_block_group_set_free_blocks_count(bg_ref->block_group,
+			sb, free_blocks);
+	bg_ref->dirty = true;
+
+	rc = ext4_filesystem_put_block_group_ref(bg_ref);
+	if (rc != EOK) {
+		EXT4FS_DBG("error in saving bg_ref \%d", rc);
+		// TODO error
+		return rc;
+	}
+
+	return EOK;
+}
+
+int ext4_balloc_free_blocks(ext4_inode_ref_t *inode_ref,
+		uint32_t first, uint32_t count)
+{
+	int rc;
+
+	ext4_filesystem_t *fs = inode_ref->fs;
+	ext4_superblock_t *sb = fs->superblock;
+
+	uint32_t block_group_first =
+			ext4_balloc_get_bgid_of_block(sb, first);
+	uint32_t block_group_last =
+			ext4_balloc_get_bgid_of_block(sb, first + count);
+
+	assert(block_group_first == block_group_last);
+
+	ext4_block_group_ref_t *bg_ref;
+	rc = ext4_filesystem_get_block_group_ref(fs, block_group_first, &bg_ref);
+	if (rc != EOK) {
+		EXT4FS_DBG("error in loading bg_ref \%d", rc);
+		return rc;
+	}
+
+	uint32_t index_in_group_first =
+			ext4_balloc_blockaddr2_index_in_group(sb, first);
+
+	uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
+			bg_ref->block_group, sb);
+
+	block_t *bitmap_block;
+	rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
+	if (rc != EOK) {
+		EXT4FS_DBG("error in loading bitmap \%d", rc);
+		return rc;
+	}
+
+	ext4_bitmap_free_bits(bitmap_block->data, index_in_group_first, count);
+
+	bitmap_block->dirty = true;
+
+	rc = block_put(bitmap_block);
+	if (rc != EOK) {
+		// Error in saving bitmap
+		ext4_filesystem_put_block_group_ref(bg_ref);
+		EXT4FS_DBG("error in saving bitmap \%d", rc);
+		return rc;
+	}
+
+	uint32_t block_size = ext4_superblock_get_block_size(sb);
+
+	// Update superblock free blocks count
+	uint32_t sb_free_blocks = ext4_superblock_get_free_blocks_count(sb);
+	sb_free_blocks += count;
+	ext4_superblock_set_free_blocks_count(sb, sb_free_blocks);
+
+	// Update inode blocks count
+	uint64_t ino_blocks = ext4_inode_get_blocks_count(sb, inode_ref->inode);
+	ino_blocks -= count * (block_size / EXT4_INODE_BLOCK_SIZE);
+	ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
+	inode_ref->dirty = true;
+
+	// Update block group free blocks count
+	uint32_t free_blocks = ext4_block_group_get_free_blocks_count(
+			bg_ref->block_group, sb);
+	free_blocks += count;
 	ext4_block_group_set_free_blocks_count(bg_ref->block_group,
 			sb, free_blocks);
Index: uspace/lib/ext4/libext4_balloc.h
===================================================================
--- uspace/lib/ext4/libext4_balloc.h	(revision 81092ce09ffeee54114d8c0a2ddfffc2cfeda3e3)
+++ uspace/lib/ext4/libext4_balloc.h	(revision 662bd71c6b5b4811d54aad7632d9f3ddc5022357)
@@ -38,4 +38,6 @@
 
 extern int ext4_balloc_free_block(ext4_inode_ref_t *, uint32_t);
+extern int ext4_balloc_free_blocks(ext4_inode_ref_t *,
+		uint32_t , uint32_t);
 extern int ext4_balloc_alloc_block(ext4_inode_ref_t *, uint32_t *);
 
Index: uspace/lib/ext4/libext4_bitmap.c
===================================================================
--- uspace/lib/ext4/libext4_bitmap.c	(revision 81092ce09ffeee54114d8c0a2ddfffc2cfeda3e3)
+++ uspace/lib/ext4/libext4_bitmap.c	(revision 662bd71c6b5b4811d54aad7632d9f3ddc5022357)
@@ -51,4 +51,53 @@
 }
 
+void ext4_bitmap_free_bits(uint8_t *bitmap, uint32_t index, uint32_t count)
+{
+	uint8_t *target;
+	uint32_t idx = index;
+	uint32_t remaining = count;
+	uint32_t byte_index;
+
+	while (((idx % 8) != 0) && (remaining > 0)) {
+
+		byte_index = idx / 8;
+		uint32_t bit_index = idx % 8;
+
+		target = bitmap + byte_index;
+
+		*target &= ~ (1 << bit_index);
+
+		idx++;
+		remaining--;
+	}
+
+	assert((idx % 8) == 0);
+
+	byte_index = idx / 8;
+	target = bitmap + byte_index;
+
+	while (remaining >= 8) {
+		*target = 0;
+
+		idx += 8;
+		remaining -= 8;
+		target++;
+	}
+
+	assert(remaining < 8);
+
+	while (remaining != 0) {
+
+		byte_index = idx / 8;
+		uint32_t bit_index = idx % 8;
+
+		target = bitmap + byte_index;
+
+		*target &= ~ (1 << bit_index);
+
+		idx++;
+		remaining--;
+	}
+}
+
 void ext4_bitmap_set_bit(uint8_t *bitmap, uint32_t index)
 {
Index: uspace/lib/ext4/libext4_bitmap.h
===================================================================
--- uspace/lib/ext4/libext4_bitmap.h	(revision 81092ce09ffeee54114d8c0a2ddfffc2cfeda3e3)
+++ uspace/lib/ext4/libext4_bitmap.h	(revision 662bd71c6b5b4811d54aad7632d9f3ddc5022357)
@@ -37,4 +37,5 @@
 
 extern void ext4_bitmap_free_bit(uint8_t *, uint32_t);
+extern void ext4_bitmap_free_bits(uint8_t *, uint32_t, uint32_t);
 extern void ext4_bitmap_set_bit(uint8_t *, uint32_t);
 extern bool ext4_bitmap_is_free_bit(uint8_t *, uint32_t);
