Index: uspace/lib/ext4/libext4_directory.c
===================================================================
--- uspace/lib/ext4/libext4_directory.c	(revision 786bd568fef4358d3eb0f23391c4c44ea260420b)
+++ uspace/lib/ext4/libext4_directory.c	(revision db2f65499a0089e9058701e253a611bcb6deb1c9)
@@ -95,4 +95,29 @@
 }
 
+uint8_t ext4_directory_entry_ll_get_inode_type(
+		ext4_superblock_t *sb, ext4_directory_entry_ll_t *de)
+{
+	if (ext4_superblock_get_rev_level(sb) == 0 &&
+		    ext4_superblock_get_minor_rev_level(sb) < 5) {
+
+			return de->inode_type;
+	}
+
+	return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
+
+}
+
+void ext4_directory_entry_ll_set_inode_type(
+		ext4_superblock_t *sb, ext4_directory_entry_ll_t *de, uint8_t type)
+{
+	if (ext4_superblock_get_rev_level(sb) == 0 &&
+			ext4_superblock_get_minor_rev_level(sb) < 5) {
+
+		de->inode_type = type;
+	}
+
+	// else do nothing
+
+}
 
 int ext4_directory_iterator_init(ext4_directory_iterator_t *it,
@@ -261,6 +286,8 @@
 
 int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * inode_ref,
-		const char *entry_name, uint32_t child_inode)
-{
+		const char *entry_name, ext4_inode_ref_t *child)
+{
+	EXT4FS_DBG("adding dentry \%s to inode \%u", entry_name, child->index);
+
 	int rc;
 
@@ -283,5 +310,5 @@
 
 			// Don't touch entry length
-			ext4_directory_entry_ll_set_inode(it.current, child_inode);
+			ext4_directory_entry_ll_set_inode(it.current, child->index);
 			ext4_directory_entry_ll_set_name_length(fs->superblock, it.current, name_len);
 			it.current_block->dirty = true;
@@ -290,9 +317,10 @@
 
 		if (entry_inode != 0) {
-
 			uint16_t used_name_len = ext4_directory_entry_ll_get_name_length(
 					fs->superblock, it.current);
 			uint16_t free_space = rec_len - 8 - (used_name_len + (4- used_name_len % 4));
 
+			EXT4FS_DBG("rec_len = \%u, free_space == \%u, required_len = \%u", rec_len, free_space, required_len);
+
 			if (free_space >= required_len) {
 				uint16_t used_len = rec_len - free_space;
@@ -301,18 +329,25 @@
 				ext4_directory_entry_ll_set_entry_length(it.current, used_len);
 
-				// Jump to newly created
-				rc = ext4_directory_iterator_next(&it);
-				if (rc != EOK) {
-					return rc;
-				}
+				// SEEK manually
+				it.current_offset += used_len;
+				ext4_directory_entry_ll_t *new_entry = it.current_block->data + it.current_offset;
 
 				// We are sure, that both entries are in the same data block
 				// dirtyness will be set now
 
-				ext4_directory_entry_ll_set_inode(it.current, child_inode);
-				ext4_directory_entry_ll_set_entry_length(it.current, free_space);
+				ext4_directory_entry_ll_set_inode(new_entry, child->index);
+				ext4_directory_entry_ll_set_entry_length(new_entry, free_space);
 				ext4_directory_entry_ll_set_name_length(
-						fs->superblock, it.current, name_len);
-				memcpy(it.current->name, entry_name, name_len);
+						fs->superblock, new_entry, name_len);
+
+				if (ext4_inode_is_type(fs->superblock, child->inode, EXT4_INODE_MODE_DIRECTORY)) {
+					ext4_directory_entry_ll_set_inode_type(
+							fs->superblock, new_entry, EXT4_DIRECTORY_FILETYPE_DIR);
+				} else {
+					ext4_directory_entry_ll_set_inode_type(
+							fs->superblock, new_entry, EXT4_DIRECTORY_FILETYPE_REG_FILE);
+				}
+
+				memcpy(new_entry->name, entry_name, name_len);
 				it.current_block->dirty = true;
 				return ext4_directory_iterator_fini(&it);
@@ -367,5 +402,5 @@
 
 	// Entry length is not affected
-	ext4_directory_entry_ll_set_inode(it.current, child_inode);
+	ext4_directory_entry_ll_set_inode(it.current, child->index);
 	ext4_directory_entry_ll_set_name_length(fs->superblock, it.current, name_len);
 	memcpy(it.current->name, entry_name, name_len);
Index: uspace/lib/ext4/libext4_directory.h
===================================================================
--- uspace/lib/ext4/libext4_directory.h	(revision 786bd568fef4358d3eb0f23391c4c44ea260420b)
+++ uspace/lib/ext4/libext4_directory.h	(revision db2f65499a0089e9058701e253a611bcb6deb1c9)
@@ -39,4 +39,13 @@
 #define EXT4_DIRECTORY_FILENAME_LEN	255
 
+#define EXT4_DIRECTORY_FILETYPE_UNKNOWN         0
+#define EXT4_DIRECTORY_FILETYPE_REG_FILE        1
+#define EXT4_DIRECTORY_FILETYPE_DIR             2
+#define EXT4_DIRECTORY_FILETYPE_CHRDEV          3
+#define EXT4_DIRECTORY_FILETYPE_BLKDEV          4
+#define EXT4_DIRECTORY_FILETYPE_FIFO            5
+#define EXT4_DIRECTORY_FILETYPE_SOCK            6
+#define EXT4_DIRECTORY_FILETYPE_SYMLINK         7
+
 /**
  * Linked list directory entry structure
@@ -73,4 +82,8 @@
 extern void ext4_directory_entry_ll_set_name_length(ext4_superblock_t *,
 		ext4_directory_entry_ll_t *, uint16_t);
+extern uint8_t ext4_directory_entry_ll_get_inode_type(ext4_superblock_t *,
+		ext4_directory_entry_ll_t *);
+extern void ext4_directory_entry_ll_set_inode_type(ext4_superblock_t *,
+		ext4_directory_entry_ll_t *, uint8_t);
 
 extern int ext4_directory_iterator_init(ext4_directory_iterator_t *,
@@ -81,5 +94,5 @@
 
 extern int ext4_directory_add_entry(ext4_filesystem_t *, ext4_inode_ref_t *,
-		const char *, uint32_t);
+		const char *, ext4_inode_ref_t *);
 extern int ext4_directory_find_entry(ext4_directory_iterator_t *,
 		ext4_inode_ref_t *, const char *);
Index: uspace/lib/ext4/libext4_ialloc.c
===================================================================
--- uspace/lib/ext4/libext4_ialloc.c	(revision 786bd568fef4358d3eb0f23391c4c44ea260420b)
+++ uspace/lib/ext4/libext4_ialloc.c	(revision db2f65499a0089e9058701e253a611bcb6deb1c9)
@@ -47,4 +47,11 @@
 }
 
+static uint32_t ext4_ialloc_index_in_group2inode(ext4_superblock_t *sb,
+		uint32_t index, uint32_t bgid)
+{
+	uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb);
+	return bgid * inodes_per_group + (index + 1);
+}
+
 static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb,
 		uint32_t inode)
@@ -127,6 +134,10 @@
 	uint32_t bgid = 0;
 	uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
+	uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
+	uint32_t avg_free_inodes = sb_free_inodes / bg_count;
 
 	while (bgid < bg_count) {
+
+		EXT4FS_DBG("testing bg \%u", bgid);
 
 		ext4_block_group_ref_t *bg_ref;
@@ -141,7 +152,7 @@
 		uint32_t used_dirs = ext4_block_group_get_used_dirs_count(bg, sb);
 
-		if ((free_inodes > 0) && (free_blocks > 0)) {
-
-			uint32_t bitmap_block_addr =  ext4_block_group_get_block_bitmap(
+		if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) {
+
+			uint32_t bitmap_block_addr =  ext4_block_group_get_inode_bitmap(
 					bg_ref->block_group, sb);
 
@@ -155,10 +166,12 @@
 			// Alloc bit
 			uint32_t inodes_in_group = ext4_superblock_get_inodes_in_group(sb, bgid);
-			rc = ext4_bitmap_find_free_bit_and_set(bitmap_block->data, 0, index, inodes_in_group);
-			if (rc == ENOSPC) {
-				block_put(bitmap_block);
-				ext4_filesystem_put_block_group_ref(bg_ref);
-				continue;
-			}
+			uint32_t index_in_group;
+			rc = ext4_bitmap_find_free_bit_and_set(
+					bitmap_block->data, 0, &index_in_group, inodes_in_group);
+//			if (rc == ENOSPC) {
+//				block_put(bitmap_block);
+//				ext4_filesystem_put_block_group_ref(bg_ref);
+//				continue;
+//			}
 
 			bitmap_block->dirty = true;
@@ -174,5 +187,5 @@
 
 			if (is_dir) {
-				used_dirs--;
+				used_dirs++;
 				ext4_block_group_set_used_dirs_count(bg, sb, used_dirs);
 			}
@@ -183,17 +196,19 @@
 			if (rc != EOK) {
 				// TODO
-			}
-
-			uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
+				EXT4FS_DBG("ERRRRR");
+			}
+
 			sb_free_inodes--;
 			ext4_superblock_set_free_inodes_count(sb, sb_free_inodes);
 
+			*index = ext4_ialloc_index_in_group2inode(sb, index_in_group, bgid);
+
 			return EOK;
 
-		} else {
-			// Not modified
-			ext4_filesystem_put_block_group_ref(bg_ref);
 		}
 
+		// Not modified
+		ext4_filesystem_put_block_group_ref(bg_ref);
+		++bgid;
 	}
 
