Index: uspace/lib/ext4/Makefile
===================================================================
--- uspace/lib/ext4/Makefile	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/Makefile	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -33,4 +33,5 @@
 
 SOURCES = \
+	libext4_bitmap.c \
 	libext4_block_group.c \
 	libext4_directory.c \
Index: uspace/lib/ext4/libext4.h
===================================================================
--- uspace/lib/ext4/libext4.h	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4.h	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -34,4 +34,5 @@
 #define LIBEXT4_LIBEXT4_H_
 
+#include "libext4_bitmap.h"
 #include "libext4_block_group.h"
 #include "libext4_directory.h"
Index: uspace/lib/ext4/libext4_bitmap.c
===================================================================
--- uspace/lib/ext4/libext4_bitmap.c	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
+++ uspace/lib/ext4/libext4_bitmap.c	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 Frantisek Princ
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libext4
+ * @{
+ */ 
+
+/**
+ * @file	libext4_bitmap.c
+ * @brief	TODO
+ */
+
+#include <errno.h>
+#include <libblock.h>
+#include <sys/types.h>
+#include "libext4.h"
+
+static void ext4_bitmap_free_bit(uint8_t *bitmap, uint32_t index)
+{
+	uint32_t byte_index = index / 8;
+	uint32_t bit_index = index % 8;
+
+	uint8_t *target = bitmap + byte_index;
+	uint8_t old_value = *target;
+
+	uint8_t new_value = old_value & (~ (1 << bit_index));
+
+	*target = new_value;
+}
+
+int ext4_bitmap_free_block(ext4_filesystem_t *fs, uint32_t block_index)
+{
+	int rc;
+	uint32_t blocks_per_group;
+	uint32_t block_group;
+	uint32_t index_in_group;
+	uint32_t bitmap_block;
+	ext4_block_group_ref_t *bg_ref;
+	block_t *block;
+
+	blocks_per_group = ext4_superblock_get_blocks_per_group(fs->superblock);
+	block_group = block_index / blocks_per_group;
+	index_in_group = block_index % blocks_per_group;
+
+	rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	bitmap_block = ext4_block_group_get_block_bitmap(bg_ref->block_group);
+
+	rc = block_get(&block, fs->device, bitmap_block, 0);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	ext4_bitmap_free_bit(block->data, index_in_group);
+
+	block->dirty = true;
+	rc = block_put(block);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	uint32_t free_blocks = ext4_block_group_get_free_blocks_count(bg_ref->block_group);
+	free_blocks++;
+	ext4_block_group_set_free_blocks_count(bg_ref->block_group, free_blocks);
+
+	rc = ext4_filesystem_put_block_group_ref(bg_ref);
+	if (rc != EOK) {
+		// TODO error
+		return rc;
+	}
+
+	return EOK;
+}
+
+
+/**
+ * @}
+ */ 
Index: uspace/lib/ext4/libext4_bitmap.h
===================================================================
--- uspace/lib/ext4/libext4_bitmap.h	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
+++ uspace/lib/ext4/libext4_bitmap.h	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Frantisek Princ
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libext4
+ * @{
+ */ 
+
+#ifndef LIBEXT4_LIBEXT4_BITMAP_H_
+#define LIBEXT4_LIBEXT4_BITMAP_H_
+
+#include <sys/types.h>
+#include "libext4_filesystem.h"
+
+extern int ext4_bitmap_free_block(ext4_filesystem_t *, uint32_t);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/ext4/libext4_block_group.c
===================================================================
--- uspace/lib/ext4/libext4_block_group.c	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4_block_group.c	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -63,4 +63,9 @@
 }
 
+void ext4_block_group_set_free_blocks_count(ext4_block_group_t *bg, uint32_t value) {
+	bg->free_blocks_count_lo = host2uint16_t_le((value << 16) >> 16);
+	bg->free_blocks_count_hi = host2uint16_t_le(value >> 16);
+}
+
 uint32_t ext4_block_group_get_free_inodes_count(ext4_block_group_t *bg)
 {
Index: uspace/lib/ext4/libext4_block_group.h
===================================================================
--- uspace/lib/ext4/libext4_block_group.h	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4_block_group.h	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -73,4 +73,5 @@
 extern uint64_t ext4_block_group_get_inode_table_first_block(ext4_block_group_t *);
 extern uint32_t ext4_block_group_get_free_blocks_count(ext4_block_group_t *);
+extern void ext4_block_group_set_free_blocks_count(ext4_block_group_t *, uint32_t);
 extern uint32_t ext4_block_group_get_free_inodes_count(ext4_block_group_t *);
 extern uint32_t ext4_block_group_get_used_dirs_count(ext4_block_group_t *);
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -251,4 +251,5 @@
 	 */
 	newref->index = index+1;
+	newref->dirty = false;
 
 	*ref = newref;
@@ -261,4 +262,8 @@
 {
 	int rc;
+
+	if (ref->dirty) {
+		ref->block->dirty = true;
+	}
 
 	rc = block_put(ref->block);
@@ -355,34 +360,95 @@
 
 
-int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t iblock)
+int ext4_filesystem_release_inode_block(ext4_filesystem_t *fs,
+		ext4_inode_ref_t *inode_ref, uint32_t iblock)
 {
 	int rc;
 	uint32_t fblock;
-
-	// TODO handle with extents
-
-	rc = ext4_filesystem_get_inode_data_block_index(fs, inode, iblock, &fblock);
-	if (rc != EOK) {
-		// TODO error
-		return rc;
-	}
-
-	// Sparse file
-	if (fblock == 0) {
-
-		//
-		return EOK;
-	}
-
-
-	// TODO vyhledat policko s ukazatelem a nastavit nulu
-
-
-	// TODO uvolnit blok v bitmape
-
-	// TODO return
-
-
-	return EOK;
+	int i;
+	int level;
+	aoff64_t block_offset_in_level;
+	uint32_t current_block;
+	uint32_t offset_in_block;
+	block_t *block;
+	ext4_inode_t *inode = inode_ref->inode;
+
+	/* TODO handle extents */
+
+	/* Handle simple case when we are dealing with direct reference */
+	if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
+		EXT4FS_DBG("direct block");
+		fblock = ext4_inode_get_direct_block(inode, (uint32_t)iblock);
+		// Sparse file
+		if (fblock == 0) {
+			return EOK;
+		}
+
+		ext4_inode_set_direct_block(inode, iblock, 0);
+		return ext4_bitmap_free_block(fs, fblock);
+	} else {
+
+		/* Determine the indirection level needed to get the desired block */
+		level = -1;
+		for (i = 1; i < 4; i++) {
+			if (iblock < fs->inode_block_limits[i]) {
+				level = i;
+				break;
+			}
+		}
+
+		if (level == -1) {
+			return EIO;
+		}
+
+		/* Compute offsets for the topmost level */
+		block_offset_in_level = iblock - fs->inode_block_limits[level-1];
+		current_block = ext4_inode_get_indirect_block(inode, level-1);
+		offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
+
+		/* Navigate through other levels, until we find the block number
+		 * or find null reference meaning we are dealing with sparse file
+		 */
+		while (level > 0) {
+			rc = block_get(&block, fs->device, current_block, 0);
+			if (rc != EOK) {
+				return rc;
+			}
+
+			current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]);
+
+			// Set zero
+			if (level == 1) {
+				((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0);
+				block->dirty = true;
+			}
+
+			rc = block_put(block);
+			if (rc != EOK) {
+				return rc;
+			}
+
+			level -= 1;
+
+			/* If we are on the last level, break here as
+			 * there is no next level to visit
+			 */
+			if (level == 0) {
+				break;
+			}
+
+			/* Visit the next level */
+			block_offset_in_level %= fs->inode_blocks_per_level[level];
+			offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];
+		}
+
+		fblock = current_block;
+
+		if (fblock == 0) {
+			return EOK;
+		}
+	}
+
+	return ext4_bitmap_free_block(fs, fblock);
+
 }
 
Index: uspace/lib/ext4/libext4_filesystem.h
===================================================================
--- uspace/lib/ext4/libext4_filesystem.h	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4_filesystem.h	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -63,5 +63,5 @@
 	ext4_inode_t *, aoff64_t iblock, uint32_t *);
 extern int ext4_filesystem_release_inode_block(ext4_filesystem_t *,
-		ext4_inode_t *, uint32_t);
+		ext4_inode_ref_t *, uint32_t);
 #endif
 
Index: uspace/lib/ext4/libext4_inode.c
===================================================================
--- uspace/lib/ext4/libext4_inode.c	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4_inode.c	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -67,6 +67,11 @@
 		return ((uint64_t)uint32_t_le2host(inode->size_hi)) << 32 |
 			    ((uint64_t)uint32_t_le2host(inode->size_lo));
-		}
+	}
 	return uint32_t_le2host(inode->size_lo);
+}
+
+void ext4_inode_set_size(ext4_inode_t *inode, uint64_t value) {
+	inode->size_lo = host2uint32_t_le((value << 32) >> 32);
+	inode->size_hi = host2uint32_t_le(value >> 32);
 }
 
Index: uspace/lib/ext4/libext4_inode.h
===================================================================
--- uspace/lib/ext4/libext4_inode.h	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/lib/ext4/libext4_inode.h	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -144,4 +144,5 @@
 	ext4_inode_t *inode;
 	uint32_t index; // Index number of this inode
+	bool dirty;
 } ext4_inode_ref_t;
 
@@ -153,4 +154,5 @@
 */
 extern uint64_t ext4_inode_get_size(ext4_superblock_t *, ext4_inode_t *);
+extern void ext4_inode_set_size(ext4_inode_t *, uint64_t);
 /*
 extern uint32_t ext4_inode_get_access_time(ext4_inode_t *);
Index: uspace/srv/fs/ext4fs/ext4fs_ops.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 5664cf64f194597acabbc06a1c44f52ae4df0710)
+++ uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 052e82dfac59bea7c0d7db91b59a859e54aedf73)
@@ -939,5 +939,5 @@
 	fs_node_t *fn;
 	ext4fs_node_t *enode;
-	ext4_inode_t *inode;
+	ext4_inode_ref_t *inode_ref;
 	ext4_filesystem_t* fs;
 	aoff64_t old_size;
@@ -951,8 +951,8 @@
 
 	enode = EXT4FS_NODE(fn);
-	inode = enode->inode_ref->inode;
+	inode_ref = enode->inode_ref;
 	fs = enode->instance->filesystem;
 
-	old_size = ext4_inode_get_size(fs->superblock, inode);
+	old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
 
 	printf("old size = \%llu, new size = \%llu\n", old_size, new_size);
@@ -961,5 +961,4 @@
 		rc = EOK;
 	} else {
-		/** AAAAAAAAAAAAAAAAAAAA */
 
 		//int rc;
@@ -989,14 +988,12 @@
 		}
 
-		// TODO dirty add to inode_ref_t
-		//ino_i->dirty = true;
+		inode_ref->dirty = true;
 
 		for (i = 0; i< blocks_count; ++i) {
 			// TODO check retval
-			ext4_filesystem_release_inode_block(fs, inode, total_blocks - i);
-			// TODO subtract inode->size
-		}
-
-		/** BBBBBBBBBBBBBBBBBBBB */
+			ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i);
+		}
+
+		ext4_inode_set_size(inode_ref->inode, new_size);
 
 	}
