Index: uspace/lib/ext4/libext4_directory.c
===================================================================
--- uspace/lib/ext4/libext4_directory.c	(revision 1d69c69133edeb2e6142a1bdb9e67cd5d12f66fa)
+++ uspace/lib/ext4/libext4_directory.c	(revision 565b6ff5e7b40ab69b0de6f22593c0abc75ab10c)
@@ -278,19 +278,48 @@
 }
 
-int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * inode_ref,
+int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * parent,
 		const char *entry_name, ext4_inode_ref_t *child)
 {
 	int rc;
 
-	// USE index if allowed
+	EXT4FS_DBG("adding entry to directory \%u [ino = \%u, name = \%s]", parent->index, child->index, entry_name);
 
 	uint16_t name_len = strlen(entry_name);
+
+	// Index adding (if allowed)
+	if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX) &&
+			ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) {
+
+		EXT4FS_DBG("trying INDEX");
+
+		rc = ext4_directory_dx_add_entry(fs, parent, name_len, entry_name);
+
+		// Check if index is not corrupted
+		if (rc != EXT4_ERR_BAD_DX_DIR) {
+
+			if (rc != EOK) {
+				return rc;
+			}
+
+			return EOK;
+		}
+
+		// Needed to clear dir index flag
+		ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
+		parent->dirty = true;
+
+		EXT4FS_DBG("index is corrupted - doing linear algorithm, index flag cleared");
+	}
+
+	// Linear algorithm
 	uint16_t required_len = 8 + name_len + (4 - name_len % 4);
 
 	ext4_directory_iterator_t it;
-	rc = ext4_directory_iterator_init(&it, fs, inode_ref, 0);
+	rc = ext4_directory_iterator_init(&it, fs, parent, 0);
 	if (rc != EOK) {
 		return rc;
 	}
+
+	uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
 
 	while (it.current != NULL) {
@@ -310,5 +339,12 @@
 			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));
+
+			uint16_t used_space = 8 + used_name_len;
+			if ((used_name_len % 4) != 0) {
+				used_space += 4 - (used_name_len % 4);
+			}
+			uint16_t free_space = rec_len - used_space;
+
+			EXT4FS_DBG("rec_len = \%u, used_space = \%u, free space = \%u", rec_len, used_space, free_space);
 
 			if (free_space >= required_len) {
@@ -319,6 +355,7 @@
 
 				// SEEK manually
-				it.current_offset += used_len;
-				ext4_directory_entry_ll_t *new_entry = it.current_block->data + it.current_offset;
+				uint32_t local_offset = (it.current_offset % block_size);
+				local_offset += used_len;
+				ext4_directory_entry_ll_t *new_entry = it.current_block->data + local_offset;
 
 				// We are sure, that both entries are in the same data block
@@ -344,9 +381,8 @@
 
 	// Compute next block index and allocate data block
-	uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
 	uint32_t block_idx = pos / block_size;
 
 	uint32_t fblock;
-	rc = ext4_filesystem_get_inode_data_block_index(fs, inode_ref->inode, block_idx, &fblock);
+	rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, block_idx, &fblock);
 	if (rc != EOK) {
 		return rc;
@@ -354,20 +390,20 @@
 
 	if (fblock == 0) {
-		rc =  ext4_balloc_alloc_block(fs, inode_ref, &fblock);
-		if (rc != EOK) {
-			return rc;
-		}
-
-		rc = ext4_filesystem_set_inode_data_block_index(fs, inode_ref, block_idx, fblock);
-		if (rc != EOK) {
-			ext4_balloc_free_block(fs, inode_ref, fblock);
-			return rc;
-		}
-
-		uint64_t inode_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
+		rc =  ext4_balloc_alloc_block(fs, parent, &fblock);
+		if (rc != EOK) {
+			return rc;
+		}
+
+		rc = ext4_filesystem_set_inode_data_block_index(fs, parent, block_idx, fblock);
+		if (rc != EOK) {
+			ext4_balloc_free_block(fs, parent, fblock);
+			return rc;
+		}
+
+		uint64_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode);
 		inode_size += block_size;
-		ext4_inode_set_size(inode_ref->inode, inode_size);
-
-		inode_ref->dirty = true;
+		ext4_inode_set_size(parent->inode, inode_size);
+
+		parent->dirty = true;
 	}
 
@@ -418,4 +454,9 @@
 
 		EXT4FS_DBG("index is corrupted - doing linear search");
+
+		// TODO Needed to clear dir index flag
+		//ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
+		//parent->dirty = true;
+
 	}
 
Index: uspace/lib/ext4/libext4_directory_index.c
===================================================================
--- uspace/lib/ext4/libext4_directory_index.c	(revision 1d69c69133edeb2e6142a1bdb9e67cd5d12f66fa)
+++ uspace/lib/ext4/libext4_directory_index.c	(revision 565b6ff5e7b40ab69b0de6f22593c0abc75ab10c)
@@ -391,4 +391,5 @@
 	}
 
+	// Hardcoded number 2 means maximum height of index tree !!!
 	ext4_directory_dx_block_t dx_blocks[2];
 	ext4_directory_dx_block_t *dx_block;
@@ -449,4 +450,52 @@
 }
 
+int ext4_directory_dx_add_entry(ext4_filesystem_t *fs,
+		ext4_inode_ref_t *parent, size_t name_size, const char *name)
+{
+	// TODO delete this command
+	return EXT4_ERR_BAD_DX_DIR;
+
+	EXT4FS_DBG("NOT REACHED");
+
+	int rc;
+
+	// get direct block 0 (index root)
+	uint32_t root_block_addr;
+	rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, 0, &root_block_addr);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	block_t *root_block;
+	rc = block_get(&root_block, fs->device, root_block_addr, BLOCK_FLAGS_NONE);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	ext4_hash_info_t hinfo;
+	rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_size, name);
+	if (rc != EOK) {
+		block_put(root_block);
+		return EXT4_ERR_BAD_DX_DIR;
+	}
+
+	// Hardcoded number 2 means maximum height of index tree !!!
+	ext4_directory_dx_block_t dx_blocks[2];
+	ext4_directory_dx_block_t *dx_block;
+	rc = ext4_directory_dx_get_leaf(&hinfo, fs, parent->inode, root_block, &dx_block, dx_blocks);
+	if (rc != EOK) {
+		block_put(root_block);
+		return EXT4_ERR_BAD_DX_DIR;
+	}
+
+	// TODO
+	/*
+	 * 1) try to write entry
+	 * 2) split leaves if necessary
+	 * 3) return
+	 */
+
+
+}
 
 
Index: uspace/lib/ext4/libext4_directory_index.h
===================================================================
--- uspace/lib/ext4/libext4_directory_index.h	(revision 1d69c69133edeb2e6142a1bdb9e67cd5d12f66fa)
+++ uspace/lib/ext4/libext4_directory_index.h	(revision 565b6ff5e7b40ab69b0de6f22593c0abc75ab10c)
@@ -123,5 +123,6 @@
 extern int ext4_directory_dx_find_entry(ext4_directory_iterator_t *,
 		ext4_filesystem_t *, ext4_inode_ref_t *, size_t, const char *);
-
+extern int ext4_directory_dx_add_entry(ext4_filesystem_t *,
+		ext4_inode_ref_t *, size_t, const char *);
 
 #endif
