Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision abd36f734cd40e6697ac37de17daa3fb8d7523eb)
+++ uspace/srv/vfs/vfs.h	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -191,6 +191,13 @@
 #define L_PARENT	64	
 
+typedef enum vfs_node_type {
+	VFS_NODE_UNKNOWN,
+	VFS_NODE_FILE,
+	VFS_NODE_DIRECTORY,
+} vfs_node_type_t;
+
 typedef struct {
 	vfs_triplet_t triplet;
+	vfs_node_type_t type;
 	size_t size;
 	unsigned lnkcnt;
@@ -214,4 +221,7 @@
 
 	link_t nh_link;		/**< Node hash-table link. */
+
+	vfs_node_type_t type;	/**< Partial info about the node type. */
+
 	size_t size;		/**< Cached size if the node is a file. */
 
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision abd36f734cd40e6697ac37de17daa3fb8d7523eb)
+++ uspace/srv/vfs/vfs_lookup.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -183,4 +183,10 @@
 		result->size = (size_t) IPC_GET_ARG4(answer);
 		result->lnkcnt = (unsigned) IPC_GET_ARG5(answer);
+		if (lflag & L_FILE)
+			result->type = VFS_NODE_FILE;
+		else if (lflag & L_DIRECTORY)
+			result->type = VFS_NODE_DIRECTORY;
+		else
+			result->type = VFS_NODE_UNKNOWN;
 	}
 
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision abd36f734cd40e6697ac37de17daa3fb8d7523eb)
+++ uspace/srv/vfs/vfs_node.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -176,4 +176,5 @@
 		node->size = result->size;
 		node->lnkcnt = result->lnkcnt;
+		node->type = result->type;
 		link_initialize(&node->nh_link);
 		rwlock_initialize(&node->contents_rwlock);
@@ -181,8 +182,14 @@
 	} else {
 		node = hash_table_get_instance(tmp, vfs_node_t, nh_link);	
+		if (node->type == VFS_NODE_UNKNOWN &&
+		    result->type != VFS_NODE_UNKNOWN) {
+			/* Upgrade the node type. */
+			node->type = result->type;
+		}
 	}
 
 	assert(node->size == result->size);
 	assert(node->lnkcnt == result->lnkcnt);
+	assert(node->type == result->type || result->type == VFS_NODE_UNKNOWN);
 
 	_vfs_node_addref(node);
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision abd36f734cd40e6697ac37de17daa3fb8d7523eb)
+++ uspace/srv/vfs/vfs_ops.c	(revision 8d2760fe0365099552ec91e6cee8c5bbd55ed273)
@@ -235,4 +235,5 @@
 			mr_res.size = (size_t) rsize;
 			mr_res.lnkcnt = (unsigned) rlnkcnt;
+			mr_res.type = VFS_NODE_DIRECTORY;
 
 			rootfs.fs_handle = fs_handle;
@@ -302,4 +303,14 @@
 	int mode = IPC_GET_ARG3(*request);
 	size_t len;
+
+	/*
+	 * Make sure that we are called with exactly one of L_FILE and
+	 * L_DIRECTORY.
+	 */
+	if ((lflag & (L_FILE | L_DIRECTORY)) == 0 ||
+	    (lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) {
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
 
 	if (oflag & O_CREAT)
@@ -457,5 +468,5 @@
 	 */
 	futex_down(&file->lock);
-	
+
 	/*
 	 * Lock the file's node so that no other client can read/write to it at
@@ -466,4 +477,13 @@
 	else
 		rwlock_write_lock(&file->node->contents_rwlock);
+
+	if (file->node->type == VFS_NODE_DIRECTORY) {
+		/*
+		 * Make sure that no one is modifying the namespace
+		 * while we are in readdir().
+		 */
+		assert(read);
+		rwlock_read_lock(&namespace_rwlock);
+	}
 	
 	int fs_phone = vfs_grab_phone(file->node->fs_handle);	
@@ -491,4 +511,7 @@
 	async_wait_for(msg, &rc);
 	size_t bytes = IPC_GET_ARG1(answer);
+
+	if (file->node->type == VFS_NODE_DIRECTORY)
+		rwlock_read_unlock(&namespace_rwlock);
 	
 	/* Unlock the VFS node. */
