Index: uspace/lib/ext4/libext4_directory.c
===================================================================
--- uspace/lib/ext4/libext4_directory.c	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_directory.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -264,4 +264,7 @@
 		ext4_inode_ref_t *child, const char *name, size_t name_len)
 {
+
+	EXT4FS_DBG("writing entry \%s, len \%u, addr = \%u", name, entry_len, (uint32_t)entry);
+
 	ext4_directory_entry_ll_set_inode(entry, child->index);
 	ext4_directory_entry_ll_set_entry_length(entry, entry_len);
@@ -291,4 +294,6 @@
 			ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) {
 
+		EXT4FS_DBG("index");
+
 		rc = ext4_directory_dx_add_entry(parent, child, name);
 
@@ -312,5 +317,5 @@
 	// Linear algorithm
 
-	uint32_t iblock, fblock;
+	uint32_t iblock = 0, fblock = 0;
 	uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
 	uint32_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode);
@@ -351,8 +356,12 @@
 	// No free block found - needed to allocate next block
 
+	iblock = 0;
+	fblock = 0;
 	rc = ext4_filesystem_append_inode_block(parent, &fblock, &iblock);
 	if (rc != EOK) {
 		return rc;
 	}
+
+	EXT4FS_DBG("using iblock \%u fblock \%u", iblock, fblock);
 
 	// Load new block
@@ -363,8 +372,12 @@
 	}
 
+	EXT4FS_DBG("loaded");
+
 	// Fill block with zeroes
 	memset(new_block->data, 0, block_size);
 	ext4_directory_entry_ll_t *block_entry = new_block->data;
 	ext4_directory_write_entry(fs->superblock, block_entry, block_size, child, name, name_len);
+
+	EXT4FS_DBG("written");
 
 	// Save new block
@@ -374,4 +387,6 @@
 		return rc;
 	}
+
+	EXT4FS_DBG("returning");
 
 	return EOK;
Index: uspace/lib/ext4/libext4_directory_index.c
===================================================================
--- uspace/lib/ext4/libext4_directory_index.c	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_directory_index.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -135,4 +135,90 @@
 /**************************************************************************/
 
+int ext4_directory_dx_init(ext4_inode_ref_t *dir)
+{
+	int rc;
+
+	uint32_t fblock;
+	rc = ext4_filesystem_get_inode_data_block_index(dir, 0, &fblock);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	block_t *block;
+	rc = block_get(&block, dir->fs->device, fblock, BLOCK_FLAGS_NONE);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	EXT4FS_DBG("fblock = \%u", fblock);
+
+	ext4_directory_dx_root_t *root = block->data;
+
+	ext4_directory_entry_ll_t *dot = (ext4_directory_entry_ll_t *)&root->dots[0];
+	ext4_directory_entry_ll_t *dot_dot = (ext4_directory_entry_ll_t *)&root->dots[1];
+
+	EXT4FS_DBG("dot len = \%u, dotdot len = \%u", ext4_directory_entry_ll_get_entry_length(dot), ext4_directory_entry_ll_get_entry_length(dot_dot));
+
+//	uint32_t block_size = ext4_superblock_get_block_size(dir->fs->superblock);
+//	uint16_t len = block_size - sizeof(ext4_directory_dx_dot_entry_t);
+
+//	ext4_directory_entry_ll_set_entry_length(dot_dot, len);
+
+	ext4_directory_dx_root_info_t *info = &(root->info);
+
+	uint8_t hash_version =
+			ext4_superblock_get_default_hash_version(dir->fs->superblock);
+
+	ext4_directory_dx_root_info_set_hash_version(info, hash_version);
+	ext4_directory_dx_root_info_set_indirect_levels(info, 0);
+	ext4_directory_dx_root_info_set_info_length(info, 8);
+
+	ext4_directory_dx_countlimit_t *countlimit =
+			(ext4_directory_dx_countlimit_t *)&root->entries;
+	ext4_directory_dx_countlimit_set_count(countlimit, 1);
+
+	uint32_t block_size = ext4_superblock_get_block_size(dir->fs->superblock);
+	uint32_t entry_space = block_size - 2 * sizeof(ext4_directory_dx_dot_entry_t)
+		- sizeof(ext4_directory_dx_root_info_t);
+	uint16_t root_limit = entry_space / sizeof(ext4_directory_dx_entry_t);
+	ext4_directory_dx_countlimit_set_limit(countlimit, root_limit);
+
+	uint32_t iblock;
+	rc = ext4_filesystem_append_inode_block(dir, &fblock, &iblock);
+	if (rc != EOK) {
+		block_put(block);
+		return rc;
+	}
+
+	block_t *new_block;
+	rc = block_get(&new_block, dir->fs->device, fblock, BLOCK_FLAGS_NOREAD);
+	if (rc != EOK) {
+		block_put(block);
+		return rc;
+	}
+
+	ext4_directory_entry_ll_t *block_entry = new_block->data;
+	ext4_directory_entry_ll_set_entry_length(block_entry, block_size);
+	ext4_directory_entry_ll_set_inode(block_entry, 0);
+
+	new_block->dirty = true;
+	rc = block_put(new_block);
+	if (rc != EOK) {
+		block_put(block);
+		return rc;
+	}
+
+	ext4_directory_dx_entry_t *entry = root->entries;
+	ext4_directory_dx_entry_set_block(entry, iblock);
+
+	block->dirty = true;
+
+	rc = block_put(block);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return EOK;
+}
 
 static int ext4_directory_hinfo_init(ext4_hash_info_t *hinfo, block_t *root_block,
@@ -771,4 +857,5 @@
 	if (rc != EOK) {
 		block_put(root_block);
+		EXT4FS_DBG("hinfo initialization error");
 		return EXT4_ERR_BAD_DX_DIR;
 	}
@@ -779,4 +866,5 @@
 	rc = ext4_directory_dx_get_leaf(&hinfo, parent, root_block, &dx_block, dx_blocks);
 	if (rc != EOK) {
+		EXT4FS_DBG("get leaf error");
 		rc = EXT4_ERR_BAD_DX_DIR;
 		goto release_index;
Index: uspace/lib/ext4/libext4_directory_index.h
===================================================================
--- uspace/lib/ext4/libext4_directory_index.h	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_directory_index.h	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -66,4 +66,5 @@
 /*********************************************************************************/
 
+extern int ext4_directory_dx_init(ext4_inode_ref_t *);
 extern int ext4_directory_dx_find_entry(ext4_directory_search_result_t *,
 		ext4_inode_ref_t *, size_t, const char *);
Index: uspace/lib/ext4/libext4_extent.c
===================================================================
--- uspace/lib/ext4/libext4_extent.c	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_extent.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -559,4 +559,5 @@
 		uint32_t iblock)
 {
+	EXT4FS_DBG("");
 	int rc;
 
@@ -568,4 +569,6 @@
 	// Trivial way - no splitting
 	if (entries < limit) {
+		EXT4FS_DBG("adding extent entry");
+
 		ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);
 		path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
@@ -581,8 +584,6 @@
 			ext4_superblock_get_block_size(inode_ref->fs->superblock);
 
-	// Trivial tree - grow
+	// Trivial tree - grow (extents were in root node)
 	if (path_ptr == path) {
-
-//		EXT4FS_DBG("splitting extent root");
 
 		uint32_t new_fblock;
@@ -592,6 +593,4 @@
 			return rc;
 		}
-
-//		EXT4FS_DBG("allocated new node \%u", new_fblock);
 
 		block_t *block;
@@ -641,10 +640,11 @@
 	}
 
+	assert(false);
+
 	// start splitting
 	uint32_t fblock = 0;
-
-	path_ptr--;
-
 	while (path_ptr > path) {
+
+		// TODO
 
 		rc = ext4_balloc_alloc_block(inode_ref, &fblock);
@@ -674,4 +674,62 @@
 			path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header);
 		}
+
+		path_ptr--;
+	}
+
+	// If splitting reached root node
+	if (path_ptr == path) {
+
+		uint32_t new_fblock;
+		rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);
+		if (rc != EOK) {
+			EXT4FS_DBG("error in block allocation");
+			return rc;
+		}
+
+		block_t *block;
+		rc = block_get(&block, inode_ref->fs->device,
+				new_fblock, BLOCK_FLAGS_NOREAD);
+		if (rc != EOK) {
+			EXT4FS_DBG("error in block_get");
+			return rc;
+		}
+
+		memset(block->data, 0, block_size);
+
+		// Move data from root to the new block
+		memcpy(block->data, inode_ref->inode->blocks,
+				EXT4_INODE_BLOCKS * sizeof(uint32_t));
+
+		path_ptr++;
+		path_ptr->block = block;
+		path_ptr->header = (ext4_extent_header_t *)block->data;
+		path_ptr->depth = ext4_extent_header_get_depth(path_ptr->header);
+		path_ptr->index = NULL;
+
+		uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
+		path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
+		ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);
+		uint16_t limit = (block_size - sizeof(ext4_extent_header_t)) /
+				sizeof(ext4_extent_t);
+		ext4_extent_header_set_max_entries_count(path_ptr->header, limit);
+
+		// Modify root (in inode)
+		path->depth = 1;
+		path->extent = NULL;
+		path->index = EXT4_EXTENT_FIRST_INDEX(path->header);
+
+		ext4_extent_header_set_depth(path->header, path_ptr->depth + 1);
+		ext4_extent_header_set_entries_count(path->header, 1);
+
+		ext4_extent_index_set_first_block(path->index, 0);
+		ext4_extent_index_set_leaf(path->index, new_fblock);
+
+		path_ptr->block->dirty = true;
+		path->block->dirty = true;
+
+		*last_path_item = path_ptr;
+
+		return EOK;
 	}
 
@@ -682,4 +740,5 @@
 		uint32_t *iblock, uint32_t *fblock)
 {
+	EXT4FS_DBG("");
 	int rc = EOK;
 
@@ -726,6 +785,5 @@
 			rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
 			if (rc != EOK) {
-			// TODO error, cleanup
-				assert(false);
+				goto finish;
 			}
 
@@ -745,11 +803,9 @@
 			rc = ext4_balloc_try_alloc_block(inode_ref, phys_block, &free);
 			if (rc != EOK) {
-				// TODO error
-				assert(false);
+				goto finish;
 			}
 
 			if (! free) {
 				// target is not free
-//				EXT4FS_DBG("target not free, \%u", phys_block);
 				goto append_extent;
 			}
@@ -763,6 +819,4 @@
 		}
 	}
-
-	assert(false);
 
 append_extent:
@@ -776,6 +830,4 @@
 	}
 
-//	EXT4FS_DBG("allocated \%u", phys_block);
-
 	rc = ext4_extent_append_extent(inode_ref, path, &path_ptr, new_block_idx);
 	if (rc != EOK) {
@@ -794,6 +846,4 @@
 	*iblock = new_block_idx;
 	*fblock = phys_block;
-
-//	EXT4FS_DBG("iblock = \%u, fblock = \%u", new_block_idx, phys_block);
 
 	// Put loaded blocks
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -323,6 +323,4 @@
 	}
 
-	// TODO dir_index initialization
-
 	rc = ext4_filesystem_get_inode_ref(fs, index, inode_ref);
 	if (rc != EOK) {
@@ -596,4 +594,6 @@
 		rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
 
+		EXT4FS_DBG("ext: loading iblock \%u, address \%u", (uint32_t)iblock, current_block);
+
 		if (rc != EOK) {
 			return rc;
@@ -917,4 +917,6 @@
 	int rc;
 
+	EXT4FS_DBG("");
+
 	// Handle extents separately
 	if (ext4_superblock_has_feature_incompatible(
@@ -932,4 +934,5 @@
 	uint32_t block_size = ext4_superblock_get_block_size(sb);
 
+	// TODO zarovnat inode size a ne assert!!!
 	assert(inode_size % block_size == 0);
 
Index: uspace/lib/ext4/libext4_superblock.c
===================================================================
--- uspace/lib/ext4/libext4_superblock.c	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_superblock.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -369,4 +369,14 @@
 }
 
+uint8_t ext4_superblock_get_default_hash_version(ext4_superblock_t *sb)
+{
+	return sb->default_hash_version;
+}
+
+void ext4_superblock_set_default_hash_version(ext4_superblock_t *sb, uint8_t version)
+{
+	sb->default_hash_version = version;
+}
+
 uint16_t ext4_superblock_get_desc_size(ext4_superblock_t *sb)
 {
Index: uspace/lib/ext4/libext4_superblock.h
===================================================================
--- uspace/lib/ext4/libext4_superblock.h	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/lib/ext4/libext4_superblock.h	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -114,6 +114,7 @@
 extern void ext4_superblock_set_last_orphan(ext4_superblock_t *, uint32_t);
 extern uint32_t* ext4_superblock_get_hash_seed(ext4_superblock_t *);
+extern uint8_t ext4_superblock_get_default_hash_version(ext4_superblock_t *);
+extern void ext4_superblock_set_default_hash_version(ext4_superblock_t *, uint8_t);
 /*
-uint8_t s_def_hash_version; // Default hash version to use
 uint8_t s_jnl_backup_type;
 */
Index: uspace/srv/fs/ext4fs/ext4fs_ops.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 81ee87cdb3976ef8c9f292ee4581984cf669aad9)
+++ uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -510,4 +510,16 @@
 		}
 
+//		if (ext4_superblock_has_feature_compatible(
+//				fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
+//
+//			rc = ext4_directory_dx_init(child->inode_ref);
+//			if (rc != EOK) {
+//				return rc;
+//			}
+//
+//			ext4_inode_set_flag(child->inode_ref->inode, EXT4_INODE_FLAG_INDEX);
+//			child->inode_ref->dirty = true;
+//		}
+
 		uint16_t parent_links = ext4_inode_get_links_count(parent->inode_ref->inode);
 		parent_links++;
