Index: uspace/app/ext2info/ext2info.c
===================================================================
--- uspace/app/ext2info/ext2info.c	(revision 9e347505f2957b1ffd7c974e4803f481117736a3)
+++ uspace/app/ext2info/ext2info.c	(revision b5085a7f51709451e41245a25f7923e899b78a3c)
@@ -590,5 +590,5 @@
 	printf("  Directory contents:\n");
 	
-	rc = ext2_directory_iterator_init(&it, fs, inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, inode_ref, 0);
 	if (rc != EOK) {
 		printf("Failed initializing directory iterator\n");
Index: uspace/lib/ext2/libext2_directory.c
===================================================================
--- uspace/lib/ext2/libext2_directory.c	(revision 9e347505f2957b1ffd7c974e4803f481117736a3)
+++ uspace/lib/ext2/libext2_directory.c	(revision b5085a7f51709451e41245a25f7923e899b78a3c)
@@ -86,32 +86,17 @@
  * @param fs pointer to filesystem structure
  * @param inode pointer to inode reference structure
+ * @param pos position within inode to start at, 0 is the first entry
  * @return EOK on success or negative error code on failure
  */
 int ext2_directory_iterator_init(ext2_directory_iterator_t *it,
-    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref)
-{
-	int rc;
-	uint32_t block_id;
-	uint32_t block_size;
-	
+    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref, aoff64_t pos)
+{	
 	it->inode_ref = inode_ref;
 	it->fs = fs;
-	
-	/* Get the first data block, so we can get the first entry */
-	rc = ext2_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0, 
-	    &block_id);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	rc = block_get(&it->current_block, fs->device, block_id, 0);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	block_size = ext2_superblock_get_block_size(fs->superblock);
-	
-	it->current_offset = 0;	
-	return ext2_directory_iterator_set(it, block_size);
+	it->current = NULL;
+	it->current_offset = 0;
+	it->current_block = NULL;
+	
+	return ext2_directory_iterator_seek(it, pos);
 }
 
@@ -124,6 +109,23 @@
 int ext2_directory_iterator_next(ext2_directory_iterator_t *it)
 {
+	uint16_t skip;
+	
+	assert(it->current != NULL);
+	
+	skip = ext2_directory_entry_ll_get_entry_length(it->current);
+	
+	return ext2_directory_iterator_seek(it, it->current_offset + skip);
+}
+
+/**
+ * Seek the directory iterator to the given byte offset within the inode.
+ * 
+ * @param it pointer to iterator to initialize
+ * @return EOK on success or negative error code on failure
+ */
+int ext2_directory_iterator_seek(ext2_directory_iterator_t *it, aoff64_t pos)
+{
 	int rc;
-	uint16_t skip;
+	
 	uint64_t size;
 	aoff64_t current_block_idx;
@@ -132,19 +134,20 @@
 	uint32_t block_size;
 	
-	assert(it->current != NULL);
-	
-	skip = ext2_directory_entry_ll_get_entry_length(it->current);
 	size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode);
 	
+	/* The iterator is not valid until we seek to the desired position */
+	it->current = NULL;
+	
 	/* Are we at the end? */
-	if (it->current_offset + skip >= size) {
-		rc = block_put(it->current_block);
-		it->current_block = NULL;
-		it->current = NULL;
-		if (rc != EOK) {
-			return rc;
+	if (pos >= size) {		
+		if (it->current_block) {
+			rc = block_put(it->current_block);
+			it->current_block = NULL;
+			if (rc != EOK) {
+				return rc;
+			}
 		}
 		
-		it->current_offset += skip;
+		it->current_offset = pos;
 		return EOK;
 	}
@@ -152,15 +155,16 @@
 	block_size = ext2_superblock_get_block_size(it->fs->superblock);
 	current_block_idx = it->current_offset / block_size;
-	next_block_idx = (it->current_offset + skip) / block_size;
-	
-	/* If we are moving accross block boundary,
+	next_block_idx = pos / block_size;
+	
+	/* If we don't have a block or are moving accross block boundary,
 	 * we need to get another block
 	 */
-	if (current_block_idx != next_block_idx) {
-		rc = block_put(it->current_block);
-		it->current_block = NULL;
-		it->current = NULL;
-		if (rc != EOK) {
-			return rc;
+	if (it->current_block == NULL || current_block_idx != next_block_idx) {		
+		if (it->current_block) {
+			rc = block_put(it->current_block);
+			it->current_block = NULL;
+			if (rc != EOK) {
+				return rc;
+			}
 		}
 		
@@ -179,8 +183,15 @@
 	}
 	
-	it->current_offset += skip;
+	it->current_offset = pos;
 	return ext2_directory_iterator_set(it, block_size);
 }
 
+/** Setup the entry at the current iterator offset.
+ * 
+ * This function checks the validity of the directory entry,
+ * before setting the data pointer.
+ *
+ * @return EOK on success or error code on failure 
+ */
 static int ext2_directory_iterator_set(ext2_directory_iterator_t *it,
     uint32_t block_size)
Index: uspace/lib/ext2/libext2_directory.h
===================================================================
--- uspace/lib/ext2/libext2_directory.h	(revision 9e347505f2957b1ffd7c974e4803f481117736a3)
+++ uspace/lib/ext2/libext2_directory.h	(revision b5085a7f51709451e41245a25f7923e899b78a3c)
@@ -71,6 +71,7 @@
 
 extern int ext2_directory_iterator_init(ext2_directory_iterator_t *,
-    ext2_filesystem_t *, ext2_inode_ref_t *);
+    ext2_filesystem_t *, ext2_inode_ref_t *, aoff64_t);
 extern int ext2_directory_iterator_next(ext2_directory_iterator_t *);
+extern int ext2_directory_iterator_seek(ext2_directory_iterator_t *, aoff64_t pos);
 extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *);
 
Index: uspace/srv/fs/ext2fs/ext2fs_ops.c
===================================================================
--- uspace/srv/fs/ext2fs/ext2fs_ops.c	(revision 9e347505f2957b1ffd7c974e4803f481117736a3)
+++ uspace/srv/fs/ext2fs/ext2fs_ops.c	(revision b5085a7f51709451e41245a25f7923e899b78a3c)
@@ -240,5 +240,5 @@
 	}
 	
-	rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref, 0);
 	if (rc != EOK) {
 		return rc;
@@ -478,5 +478,5 @@
 	}
 	
-	rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref, 0);
 	if (rc != EOK) {
 		EXT2FS_DBG("error %u", rc);
@@ -818,5 +818,5 @@
 {
 	ext2_directory_iterator_t it;
-	aoff64_t cur;
+	aoff64_t next;
 	uint8_t *buf;
 	size_t name_size;
@@ -824,5 +824,5 @@
 	bool found = false;
 	
-	rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref);
+	rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref, pos);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -831,11 +831,8 @@
 	}
 	
-	/* Find the index we want to read
-	 * Note that we need to iterate and count as
-	 * the underlying structure is a linked list
-	 * Moreover, we want to skip . and .. entries
+	/* Find next interesting directory entry.
+	 * We want to skip . and .. entries
 	 * as these are not used in HelenOS
 	 */
-	cur = 0;
 	while (it.current != NULL) {
 		if (it.current->inode == 0) {
@@ -851,25 +848,21 @@
 		}
 		
-		/* Is this the dir entry we want to read? */
-		if (cur == pos) {
-			/* The on-disk entry does not contain \0 at the end
-			 * end of entry name, so we copy it to new buffer
-			 * and add the \0 at the end
-			 */
-			buf = malloc(name_size+1);
-			if (buf == NULL) {
-				ext2_directory_iterator_fini(&it);
-				async_answer_0(callid, ENOMEM);
-				async_answer_0(rid, ENOMEM);
-				return;
-			}
-			memcpy(buf, &it.current->name, name_size);
-			*(buf+name_size) = 0;
-			found = true;
-			(void) async_data_read_finalize(callid, buf, name_size+1);
-			free(buf);
-			break;
-		}
-		cur++;
+		/* The on-disk entry does not contain \0 at the end
+			* end of entry name, so we copy it to new buffer
+			* and add the \0 at the end
+			*/
+		buf = malloc(name_size+1);
+		if (buf == NULL) {
+			ext2_directory_iterator_fini(&it);
+			async_answer_0(callid, ENOMEM);
+			async_answer_0(rid, ENOMEM);
+			return;
+		}
+		memcpy(buf, &it.current->name, name_size);
+		*(buf+name_size) = 0;
+		found = true;
+		(void) async_data_read_finalize(callid, buf, name_size+1);
+		free(buf);
+		break;
 		
 skip:
@@ -883,4 +876,13 @@
 	}
 	
+	if (found) {
+		rc = ext2_directory_iterator_next(&it);
+		if (rc != EOK) {
+			async_answer_0(rid, rc);
+			return;
+		}
+		next = it.current_offset;
+	}
+	
 	rc = ext2_directory_iterator_fini(&it);
 	if (rc != EOK) {
@@ -890,5 +892,5 @@
 	
 	if (found) {
-		async_answer_1(rid, EOK, 1);
+		async_answer_1(rid, EOK, next-pos);
 	}
 	else {
