Index: uspace/lib/ext4/libext4_balloc.c
===================================================================
--- uspace/lib/ext4/libext4_balloc.c	(revision 9c2d19d685a297875f524abe2f67a4c4c364d759)
+++ uspace/lib/ext4/libext4_balloc.c	(revision 3e2952b53c099b9f46a754f777d54d40c2269a6d)
@@ -161,9 +161,8 @@
 			ext4_balloc_get_bgid_of_block(sb, first);
 	uint32_t block_group_last =
-			ext4_balloc_get_bgid_of_block(sb, first + count);
-
-	EXT4FS_DBG("first =\%u (bg \%u), last = \%u (bg \%u)", first,  block_group_first, first + count, block_group_last);
-
-	ext4_block_group_ref_t *bg_ref;
+			ext4_balloc_get_bgid_of_block(sb, first + count - 1);
+
+	assert(block_group_first == block_group_last);
+
 	rc = ext4_filesystem_get_block_group_ref(fs, block_group_first, &bg_ref);
 	if (rc != EOK) {
Index: uspace/lib/ext4/libext4_extent.c
===================================================================
--- uspace/lib/ext4/libext4_extent.c	(revision 9c2d19d685a297875f524abe2f67a4c4c364d759)
+++ uspace/lib/ext4/libext4_extent.c	(revision 3e2952b53c099b9f46a754f777d54d40c2269a6d)
@@ -400,6 +400,5 @@
 	int rc;
 
-	// 1) Delete iblock and successors in the same extent
-
+	// Find the first extent to modify
 	ext4_extent_path_t *path;
 	rc = ext4_extent_find_extent(inode_ref, iblock_from, &path);
@@ -408,4 +407,5 @@
 	}
 
+	// Jump to last item of the path (extent)
 	ext4_extent_path_t *path_ptr = path;
 	while (path_ptr->depth != 0) {
@@ -415,4 +415,5 @@
 	assert(path_ptr->extent != NULL);
 
+	// First extent maybe released partially
 	uint32_t first_fblock;
 	first_fblock = ext4_extent_get_start(path_ptr->extent) + iblock_from;
@@ -425,77 +426,68 @@
 
 	rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
+	if (rc != EOK) {
+		// TODO goto cleanup
+		EXT4FS_DBG("ERROR");
+		return rc;
+	}
 
 	block_count -= delete_count;
 	ext4_extent_set_block_count(path_ptr->extent, block_count);
 
-	path_ptr->block->dirty = true;
-
-	bool check_tree = false;
-
-	uint16_t old_root_entries = ext4_extent_header_get_entries_count(path->header);
-
+	uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
+	ext4_extent_t *tmp_ext = path_ptr->extent + 1;
+	ext4_extent_t *stop_ext = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
+
+	// If first extent empty, release it
 	if (block_count == 0) {
-		uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
 		entries--;
 		ext4_extent_header_set_entries_count(path_ptr->header, entries);
-
-		// If empty leaf, will be released and the whole tree must be checked
-		if (path_ptr != path) {
-			rc = ext4_balloc_free_block(inode_ref, path_ptr->block->pba);
-			if (rc != EOK) {
-				EXT4FS_DBG("ERROR");
-				// TODO
-			}
-			check_tree = true;
-		}
-	}
-
+	}
+
+	// Release all successors of the first extent in the same node
+	while (tmp_ext < stop_ext) {
+		first_fblock = ext4_extent_get_start(tmp_ext);
+		delete_count = ext4_extent_get_block_count(tmp_ext);
+
+		rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count);
+		if (rc != EOK) {
+			// TODO goto cleanup
+			EXT4FS_DBG("ERROR");
+			return rc;
+		}
+
+		entries--;
+		ext4_extent_header_set_entries_count(path_ptr->header, entries);
+
+		tmp_ext++;
+	}
+
+	// If leaf node is empty, the whole tree must be checked and the node will be released
+	bool check_tree = false;
+
+	// Don't release root block (including inode data) !!!
+	if ((path_ptr != path) && (entries == 0)) {
+		rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba);
+		if (rc != EOK) {
+			EXT4FS_DBG("ERROR");
+			// TODO goto cleanup
+			return rc;
+		}
+		check_tree = true;
+	}
+
+	// Jump to the parent
 	--path_ptr;
 
-	while ((path_ptr >= path) && check_tree) {
-
-		if (path_ptr > path) {
-
-			EXT4FS_DBG("not root");
-			uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
+	// release all successors in all levels
+	while(path_ptr >= path) {
+		entries = ext4_extent_header_get_entries_count(path_ptr->header);
+		ext4_extent_index_t *index = path_ptr->index + 1;
+		ext4_extent_index_t *stop =
+				EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;
+
+		if (check_tree) {
 			entries--;
 			ext4_extent_header_set_entries_count(path_ptr->header, entries);
-
-			if (entries == 0) {
-				rc = ext4_balloc_free_block(inode_ref, path_ptr->block->pba);
-				if (rc != EOK) {
-					EXT4FS_DBG("ERROR");
-					// TODO
-				}
-			} else {
-				break;
-			}
-
-		} else {
-			EXT4FS_DBG("root");
-
-			// TODO tady je BUG asi
-
-			uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
-			entries--;
-			ext4_extent_header_set_entries_count(path_ptr->header, entries);
-
-			break;
-		}
-
-		path_ptr--;
-	}
-
-	ext4_extent_header_t *header = path->header;
-
-	// 2) delete or successors first level extents/indexes
-	if (ext4_extent_header_get_depth(header)) {
-
-		ext4_extent_index_t *index = path->index + 1;
-		ext4_extent_index_t *stop = EXT4_EXTENT_FIRST_INDEX(header) +
-				old_root_entries;
-
-		if (index < stop) {
-			inode_ref->dirty = true;
 		}
 
@@ -504,38 +496,31 @@
 			if (rc != EOK) {
 				EXT4FS_DBG("ERR");
-				// TODO error
+				// TODO goto cleanup
+				return rc;
 			}
 			++index;
-
-			uint16_t entries = ext4_extent_header_get_entries_count(header);
-			entries--;
-			ext4_extent_header_set_entries_count(header, entries);
-
-		}
-
-	} else {
-
-		ext4_extent_t *extent = path->extent + 1;
-		ext4_extent_t *stop = EXT4_EXTENT_FIRST(header) +
-				old_root_entries;
-
-		if (extent != stop) {
-			inode_ref->dirty = true;
-		}
-
-		while (extent < stop) {
-			rc = ext4_extent_release(inode_ref, extent);
+			--entries;
+			ext4_extent_header_set_entries_count(path_ptr->header, entries);
+		}
+
+		path_ptr->block->dirty = true;
+
+		if ((entries == 0) && (path_ptr != path)) {
+			rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba);
 			if (rc != EOK) {
-				EXT4FS_DBG("ERR");
-				// TODO error
+				EXT4FS_DBG("ERROR");
+				// TODO goto cleanup
+				return rc;
 			}
-			++extent;
-
-			uint16_t entries = ext4_extent_header_get_entries_count(header);
-			entries--;
-			ext4_extent_header_set_entries_count(header, entries);
-		}
-	}
-
+			check_tree = true;
+		} else {
+			check_tree = false;
+		}
+
+		--path_ptr;
+	}
+
+
+	// Finish
 	uint16_t depth = path->depth;
 
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision 9c2d19d685a297875f524abe2f67a4c4c364d759)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision 3e2952b53c099b9f46a754f777d54d40c2269a6d)
@@ -366,4 +366,14 @@
 	int rc;
 
+	ext4_filesystem_t *fs = inode_ref->fs;
+
+	if (ext4_superblock_has_feature_incompatible(
+			fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) &&
+				ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) {
+
+		// Data structures are released during truncate operation...
+		goto finish;
+	}
+
 	// release all indirect (no data) blocks
 
@@ -378,6 +388,4 @@
 		ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
 	}
-
-	ext4_filesystem_t *fs = inode_ref->fs;
 
 	block_t *block;
@@ -472,4 +480,5 @@
 	}
 
+finish:
 	inode_ref->dirty = true;
 
