Index: uspace/lib/ext4/libext4_directory.c
===================================================================
--- uspace/lib/ext4/libext4_directory.c	(revision 12f552207db9b0ddb3dbefce8346fd46011fbe95)
+++ uspace/lib/ext4/libext4_directory.c	(revision 7bc4508b0a5fc0e8fc18a3a4db9c3457466964e2)
@@ -66,4 +66,40 @@
 }
 
+uint8_t ext4_directory_dx_root_info_get_hash_version(ext4_directory_dx_root_info_t *root_info)
+{
+	return root_info->hash_version;
+}
+
+uint8_t ext4_directory_dx_root_info_get_info_length(ext4_directory_dx_root_info_t *root_info)
+{
+	return root_info->info_length;
+}
+
+uint8_t ext4_directory_dx_root_info_get_indirect_levels(ext4_directory_dx_root_info_t *root_info)
+{
+	return root_info->indirect_levels;
+}
+
+uint16_t ext4_directory_dx_countlimit_get_limit(ext4_directory_dx_countlimit_t *countlimit)
+{
+	return uint16_t_le2host(countlimit->limit);
+}
+uint16_t ext4_directory_dx_countlimit_get_count(ext4_directory_dx_countlimit_t *countlimit)
+{
+	return uint16_t_le2host(countlimit->count);
+}
+
+uint32_t ext4_directory_dx_entry_get_hash(ext4_directory_dx_entry_t *entry)
+{
+	return uint32_t_le2host(entry->hash);
+}
+
+uint32_t ext4_directory_dx_entry_get_block(ext4_directory_dx_entry_t *entry)
+{
+	return uint32_t_le2host(entry->block);
+}
+
+
+
 int ext4_directory_iterator_init(ext4_directory_iterator_t *it,
     ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, aoff64_t pos)
@@ -209,4 +245,150 @@
 }
 
+int ext4_directory_dx_find_entry(ext4_directory_iterator_t *it,
+		ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, const char *name)
+{
+	int rc;
+	uint32_t fblock;
+	block_t *phys_block;
+	ext4_directory_dx_root_t *root;
+	uint32_t hash;
+	ext4_directory_dx_hash_info_t hinfo;
+
+	// get direct block 0 (index root)
+	rc = ext4_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0, &fblock);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	rc = block_get(&phys_block, fs->device, fblock, BLOCK_FLAGS_NONE);
+	if (rc != EOK) {
+		it->current_block = NULL;
+			return rc;
+	}
+
+	// Now having index root
+	root = (ext4_directory_dx_root_t *)phys_block->data;
+
+	// Check hash version - only if supported
+	EXT4FS_DBG("hash_version = \%u", root->info.hash_version);
+
+	// Check unused flags
+	if (root->info.unused_flags != 0) {
+		EXT4FS_DBG("ERR: unused_flags = \%u", root->info.unused_flags);
+		block_put(phys_block);
+		return EXT4_ERR_BAD_DX_DIR;
+	}
+
+	// Check indirect levels
+	if (root->info.indirect_levels > 1) {
+		EXT4FS_DBG("ERR: indirect_levels = \%u", root->info.indirect_levels);
+		block_put(phys_block);
+		return EXT4_ERR_BAD_DX_DIR;
+	}
+
+	uint32_t bs = ext4_superblock_get_block_size(fs->superblock);
+
+	uint32_t entry_space = bs - 2* sizeof(ext4_directory_dx_dot_entry_t) - sizeof(ext4_directory_dx_root_info_t);
+    entry_space = entry_space / sizeof(ext4_directory_dx_entry_t);
+
+
+    uint32_t limit = ext4_directory_dx_countlimit_get_limit((ext4_directory_dx_countlimit_t *)&root->entries);
+    uint32_t count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)&root->entries);
+
+    if (limit != entry_space) {
+		block_put(phys_block);
+    	return EXT4_ERR_BAD_DX_DIR;
+	}
+
+	if ((count == 0) || (count > limit)) {
+		block_put(phys_block);
+		return EXT4_ERR_BAD_DX_DIR;
+	}
+
+	/* DEBUG list
+    for (uint16_t i = 0; i < count; ++i) {
+    	uint32_t hash = ext4_directory_dx_entry_get_hash(&root->entries[i]);
+    	uint32_t block = ext4_directory_dx_entry_get_block(&root->entries[i]);
+    	EXT4FS_DBG("hash = \%u, block = \%u", hash, block);
+    }
+    */
+
+	hinfo.hash_version = ext4_directory_dx_root_info_get_hash_version(&root->info);
+	if ((hinfo.hash_version <= EXT4_DIRECTORY_DX_HASH_TEA)
+			&& (ext4_superblock_has_flag(fs->superblock, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
+		// 3 is magic from ext4 linux implementation
+		hinfo.hash_version += 3;
+	}
+
+	hinfo.seed = ext4_superblock_get_hash_seed(fs->superblock);
+	hinfo.hash = 0;
+	if (name) {
+		ext4_directory_hash(&hinfo, name);
+	}
+
+	hash = hinfo.hash;
+
+	ext4_directory_dx_entry_t *p, *q, *m;
+
+	// TODO cycle
+	// while (true)
+
+		p = &root->entries[1];
+		q = &root->entries[count - 1];
+
+		while (p <= q) {
+			m = p + (q - p) / 2;
+			if (ext4_directory_dx_entry_get_hash(m) > hash) {
+				q = m - 1;
+			} else {
+				p = m + 1;
+			}
+		}
+
+		/* TODO move to leaf or next node
+		at = p - 1;
+		dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
+        frame->bh = bh;
+        frame->entries = entries;
+        frame->at = at;
+
+        if (indirect == 0) {
+			// TODO write return values !!!
+        	return EOK;
+        }
+
+        indirect--;
+
+		// TODO read next block
+		if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
+                        goto fail2;
+		at = entries = ((struct dx_node *) bh->b_data)->entries;
+		if (dx_get_limit(entries) != dx_node_limit (dir)) {
+        	ext4_warning(dir->i_sb, "dx entry: limit != node limit");
+			brelse(bh);
+            *err = ERR_BAD_DX_DIR;
+			goto fail2;
+		}
+		frame++;
+		frame->bh = NULL;
+		 */
+
+	// } END WHILE
+
+
+	// TODO delete it !!!
+	return EXT4_ERR_BAD_DX_DIR;
+
+	if ((it->current == NULL) || (it->current->inode == 0)) {
+			return ENOENT;
+	}
+
+	return EOK;
+}
+
+void ext4_directory_hash(ext4_directory_dx_hash_info_t *hinfo, const char* name)
+{
+	// TODO
+}
 
 /**
Index: uspace/lib/ext4/libext4_directory.h
===================================================================
--- uspace/lib/ext4/libext4_directory.h	(revision 12f552207db9b0ddb3dbefce8346fd46011fbe95)
+++ uspace/lib/ext4/libext4_directory.h	(revision 7bc4508b0a5fc0e8fc18a3a4db9c3457466964e2)
@@ -64,4 +64,9 @@
 /* Structures for indexed directory */
 
+typedef struct ext4_directory_dx_countlimit {
+	uint16_t limit;
+    uint16_t count;
+} ext4_directory_dx_countlimit_t;
+
 typedef struct ext4_directory_dx_dot_entry {
 	uint32_t inode;
@@ -87,11 +92,26 @@
 typedef struct ext4_directory_dx_root {
 		ext4_directory_dx_dot_entry_t dots[2];
-		// TODO insert root info items instead of special datatype
 		ext4_directory_dx_root_info_t info;
-		ext4_directory_dx_entry_t *entries;
+		ext4_directory_dx_entry_t entries[0];
 } ext4_directory_dx_root_t;
 
+typedef struct ext4_directory_dx_hash_info {
+	uint32_t hash;
+	uint32_t minor_hash;
+	uint32_t hash_version;
+	uint32_t *seed;
+} ext4_directory_dx_hash_info_t;
 
-#define EXT4_DIRECTORY_HTREE_EOF  0x7fffffff
+
+#define EXT4_ERR_BAD_DX_DIR			(-75000)
+
+#define EXT4_DIRECTORY_DX_HASH_LEGACY				0
+#define EXT4_DIRECTORY_DX_HASH_HALF_MD4				1
+#define EXT4_DIRECTORY_DX_HASH_TEA					2
+#define EXT4_DIRECTORY_DX_HASH_LEGACY_UNSIGNED		3
+#define EXT4_DIRECTORY_DX_HASH_HALF_MD4_UNSIGNED	4
+#define EXT4_DIRECTORY_DX_HASH_TEA_UNSIGNED			5
+
+#define EXT4_DIRECTORY_HTREE_EOF	0x7fffffff
 
 
@@ -102,4 +122,14 @@
     ext4_superblock_t *, ext4_directory_entry_ll_t *);
 
+extern uint8_t ext4_directory_dx_root_info_get_hash_version(ext4_directory_dx_root_info_t *);
+extern uint8_t ext4_directory_dx_root_info_get_info_length(ext4_directory_dx_root_info_t *);
+extern uint8_t ext4_directory_dx_root_info_get_indirect_levels(ext4_directory_dx_root_info_t *);
+
+extern uint16_t ext4_directory_dx_countlimit_get_limit(ext4_directory_dx_countlimit_t *);
+extern uint16_t ext4_directory_dx_countlimit_get_count(ext4_directory_dx_countlimit_t *);
+
+extern uint32_t ext4_directory_dx_entry_get_hash(ext4_directory_dx_entry_t *);
+extern uint32_t ext4_directory_dx_entry_get_block(ext4_directory_dx_entry_t *);
+
 extern int ext4_directory_iterator_init(ext4_directory_iterator_t *,
 		ext4_filesystem_t *, ext4_inode_ref_t *, aoff64_t);
@@ -107,4 +137,8 @@
 extern int ext4_directory_iterator_seek(ext4_directory_iterator_t *, aoff64_t pos);
 extern int ext4_directory_iterator_fini(ext4_directory_iterator_t *);
+extern int ext4_directory_dx_find_entry(ext4_directory_iterator_t *,
+		ext4_filesystem_t *, ext4_inode_ref_t *, const char *);
+
+extern void ext4_directory_hash(ext4_directory_dx_hash_info_t *, const char* name);
 
 #endif
Index: uspace/lib/ext4/libext4_inode.c
===================================================================
--- uspace/lib/ext4/libext4_inode.c	(revision 12f552207db9b0ddb3dbefce8346fd46011fbe95)
+++ uspace/lib/ext4/libext4_inode.c	(revision 7bc4508b0a5fc0e8fc18a3a4db9c3457466964e2)
@@ -176,5 +176,6 @@
 
 // Flags checker
-bool ext4_inode_has_flag(ext4_inode_t *inode, uint32_t flag) {
+bool ext4_inode_has_flag(ext4_inode_t *inode, uint32_t flag)
+{
 	if (ext4_inode_get_flags(inode) & flag) {
 		return true;
Index: uspace/lib/ext4/libext4_superblock.c
===================================================================
--- uspace/lib/ext4/libext4_superblock.c	(revision 12f552207db9b0ddb3dbefce8346fd46011fbe95)
+++ uspace/lib/ext4/libext4_superblock.c	(revision 7bc4508b0a5fc0e8fc18a3a4db9c3457466964e2)
@@ -185,8 +185,27 @@
 
 
+uint32_t* ext4_superblock_get_hash_seed(ext4_superblock_t *sb)
+{
+	return sb->hash_seed;
+}
+
+uint32_t ext4_superblock_get_flags(ext4_superblock_t *sb)
+{
+	return uint32_t_le2host(sb->flags);
+}
+
+
 /*
  * More complex superblock functions
  */
 
+bool ext4_superblock_has_flag(ext4_superblock_t *sb, uint32_t flag)
+{
+	if (ext4_superblock_get_flags(sb) & flag) {
+		return true;
+	}
+	return false;
+}
+
 int ext4_superblock_read_direct(service_id_t service_id,
     ext4_superblock_t **superblock)
Index: uspace/lib/ext4/libext4_superblock.h
===================================================================
--- uspace/lib/ext4/libext4_superblock.h	(revision 12f552207db9b0ddb3dbefce8346fd46011fbe95)
+++ uspace/lib/ext4/libext4_superblock.h	(revision 7bc4508b0a5fc0e8fc18a3a4db9c3457466964e2)
@@ -109,5 +109,5 @@
 	uint16_t min_extra_isize; // All inodes have at least # bytes
 	uint16_t want_extra_isize; // New inodes should reserve # bytes
-	uint32_t lags; // Miscellaneous flags
+	uint32_t flags; // Miscellaneous flags
 	uint16_t raid_stride; // RAID stride
 	uint16_t mmp_interval; // # seconds to wait in MMP checking
@@ -144,4 +144,12 @@
 #define EXT4_SUPERBLOCK_OS_HURD		1
 
+/*
+ * Misc. filesystem flags
+ */
+#define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH	0x0001  /* Signed dirhash in use */
+#define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH	0x0002  /* Unsigned dirhash in use */
+#define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS	0x0004  /* to test development code */
+
+
 extern uint32_t ext4_superblock_get_inodes_count(ext4_superblock_t *);
 extern uint64_t ext4_superblock_get_blocks_count(ext4_superblock_t *);
@@ -191,5 +199,8 @@
 uint32_t s_journal_dev; // Device number of journal file
 uint32_t s_last_orphan; // Head of list of inodes to delete
-uint32_t s_hash_seed[4]; // HTREE hash seed
+*/
+extern uint32_t* ext4_superblock_get_hash_seed(ext4_superblock_t *);
+
+/*
 uint8_t s_def_hash_version; // Default hash version to use
 uint8_t s_jnl_backup_type;
@@ -201,5 +212,7 @@
 uint16_t s_min_extra_isize; // All inodes have at least # bytes
 uint16_t s_want_extra_isize; // New inodes should reserve # bytes
-uint32_t s_flags; // Miscellaneous flags
+*/
+extern uint32_t ext4_superblock_get_flags(ext4_superblock_t *);
+/*
 uint16_t s_raid_stride; // RAID stride
 uint16_t s_mmp_interval; // # seconds to wait in MMP checking
@@ -229,4 +242,5 @@
 
 /* More complex superblock functions */
+extern bool ext4_superblock_has_flag(ext4_superblock_t *, uint32_t);
 extern int ext4_superblock_read_direct(service_id_t, ext4_superblock_t **);
 extern int ext4_superblock_check_sanity(ext4_superblock_t *);
