Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 90e60259463688b61f97437e5c72ec749b308562)
+++ uspace/srv/vfs/vfs.c	(revision 7313e7a1ff97e029dfe0f5338f14e48064433810)
@@ -45,4 +45,5 @@
 #include <as.h>
 #include <libadt/list.h>
+#include <atomic.h>
 #include "vfs.h"
 
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision 90e60259463688b61f97437e5c72ec749b308562)
+++ uspace/srv/vfs/vfs.h	(revision 7313e7a1ff97e029dfe0f5338f14e48064433810)
@@ -129,5 +129,5 @@
 extern link_t fs_head;		/**< List of registered file systems. */
 
-extern vfs_node_t *rootfs;	/**< Root node of the root file system. */
+extern vfs_node_t rootfs;	/**< Root node of the root file system. */
 
 #define MAX_PATH_LEN		(64 * 1024)
@@ -149,8 +149,7 @@
 extern void vfs_release_phone(int);
 
-extern int fs_name_to_handle(char *name, bool lock);
+extern int fs_name_to_handle(char *, bool);
 
-extern int vfs_lookup_internal(char *path, size_t len, vfs_node_t *result,
-    vfs_node_t *altroot);
+extern int vfs_lookup_internal(char *, size_t, vfs_node_t *, vfs_node_t *);
 
 extern void vfs_register(ipc_callid_t, ipc_call_t *);
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision 90e60259463688b61f97437e5c72ec749b308562)
+++ uspace/srv/vfs/vfs_lookup.c	(revision 7313e7a1ff97e029dfe0f5338f14e48064433810)
@@ -73,7 +73,7 @@
 		root = altroot;
 	else
-		root = rootfs;
+		root = &rootfs;
 
-	if (!root)
+	if (!root->fs_handle)
 		return ENOENT;
 	
Index: uspace/srv/vfs/vfs_mount.c
===================================================================
--- uspace/srv/vfs/vfs_mount.c	(revision 90e60259463688b61f97437e5c72ec749b308562)
+++ uspace/srv/vfs/vfs_mount.c	(revision 7313e7a1ff97e029dfe0f5338f14e48064433810)
@@ -46,8 +46,152 @@
 #include "vfs.h"
 
-vfs_node_t *rootfs = NULL;
+vfs_node_t rootfs = { 0 };
+
+static int lookup_root(int fs_handle, int dev_handle, vfs_node_t *root)
+{
+	vfs_node_t altroot = {
+		.fs_handle = fs_handle,
+		.dev_handle = dev_handle,
+		/*
+		 * At this point, we don't know what is the index of the root
+		 * node. Finally, that's what this function is about.
+		 */
+	};
+
+	return vfs_lookup_internal("/", 1, root, &altroot);
+}
 
 void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
 {
+	int dev_handle;
+
+	/*
+	 * We expect the library to do the device-name to device-handle
+	 * translation for us, thus the device handle will arrive as ARG1
+	 * in the request.
+	 */
+	dev_handle = IPC_GET_ARG1(*request);
+
+	/*
+	 * For now, don't make use of ARG2 and ARG3, but they can be used to
+	 * carry mount options in the future.
+	 */
+
+	/*
+	 * Now, we expect the client to send us data with the name of the file
+	 * system and the path of the mountpoint.
+	 */
+	ipc_callid_t callid;
+	ipc_call_t call;
+	size_t size;
+	if (!ipc_data_receive(&callid, &call, NULL, &size)) {
+		ipc_answer_fast(callid, EINVAL, 0, 0);
+		ipc_answer_fast(rid, EINVAL, 0, 0);
+		return;
+	}
+
+	/*
+	 * There is no sense in receiving data that can't hold a single
+	 * character of path. We won't accept data that exceed certain limits
+	 * either.
+	 */
+	if ((size < FS_NAME_MAXLEN + 1) ||
+	    (size > FS_NAME_MAXLEN + MAX_PATH_LEN)) {
+		ipc_answer_fast(callid, EINVAL, 0, 0);
+		ipc_answer_fast(rid, EINVAL, 0, 0);
+		return;
+	}
+
+	/*
+	 * Allocate buffer for the data being received.
+	 */
+	uint8_t *buf;
+	buf = malloc(size);
+	if (!buf) {
+		ipc_answer_fast(callid, ENOMEM, 0, 0);
+		ipc_answer_fast(rid, ENOMEM, 0, 0);
+		return;
+	}
+
+	/*
+	 * Deliver the data.
+	 */
+	(void) ipc_data_deliver(callid, &call, buf, size);
+
+	char fs_name[FS_NAME_MAXLEN + 1];
+	memcpy(fs_name, buf, FS_NAME_MAXLEN);
+	fs_name[FS_NAME_MAXLEN] = '\0';
+
+	/*
+	 * Check if we know a file system with the same name as is in fs_name.
+	 * This will also give us its file system handle.
+	 */
+	int fs_handle = fs_name_to_handle(fs_name, true);
+	if (!fs_handle) {
+		free(buf);
+		ipc_answer_fast(rid, ENOENT, 0, 0);
+		return;
+	}
+
+	/*
+	 * Lookup the root node of the filesystem being mounted.
+	 */
+	int rc;
+	vfs_node_t mounted_root;
+	rc = lookup_root(fs_handle, dev_handle, &mounted_root);
+	if (rc != EOK) {
+		free(buf);
+		ipc_answer_fast(rid, rc, 0, 0);
+		return;
+	}
+
+	/*
+	 * Finally, we need to resolve the path to the mountpoint. 
+	 */
+	vfs_node_t mp;
+	if (rootfs.fs_handle) {
+		/*
+		 * We already have the root FS.
+		 */
+		rc = vfs_lookup_internal((char *) (buf + FS_NAME_MAXLEN),
+		    size - FS_NAME_MAXLEN, &mp, NULL);
+		if (rc != EOK) {
+			/*
+			 * The lookup failed for some reason.
+			 */
+			free(buf);
+			ipc_answer_fast(rid, rc, 0, 0);
+			return;
+		}
+	} else {
+		/*
+		 * We still don't have the root file system mounted.
+		 */
+		if ((size - FS_NAME_MAXLEN == 1) &&
+		    (buf[FS_NAME_MAXLEN] == '/')) {
+			/*
+			 * For this simple, but important case, we are done.
+			 */
+			rootfs = mounted_root;
+			free(buf);
+			ipc_answer_fast(rid, EOK, 0, 0);
+			return;
+		} else {
+			/*
+			 * We can't resolve this without the root filesystem
+			 * being mounted first.
+			 */
+			free(buf);
+			ipc_answer_fast(rid, ENOENT, 0, 0);
+			return;
+		}
+	}
+		
+	/*
+	 * At this point, we have all necessary pieces: file system and device
+	 * handles, and we know the mount point VFS node and also the root node
+	 * of the file system being mounted.
+	 */
+	
 }
 
