Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision cf95bc0cb5a4fbbb4ff76dd9072c26acb9072d93)
+++ uspace/lib/libfs/libfs.c	(revision fc0110df7ea7e14571f47118909114c5dbbbd866)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2008 Jakub Jermar 
+ * Copyright (c) 2009 Jakub Jermar 
  * All rights reserved.
  *
@@ -123,4 +123,83 @@
 }
 
+void fs_node_initialize(fs_node_t *fn)
+{
+	memset(fn, 0, sizeof(fs_node_t));
+}
+
+void libfs_mount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
+{
+	dev_handle_t mp_dev_handle = (dev_handle_t)IPC_GET_ARG1(*request);
+	fs_index_t mp_fs_index = (fs_index_t)IPC_GET_ARG2(*request);
+	fs_handle_t mr_fs_handle = (fs_handle_t)IPC_GET_ARG3(*request);
+	dev_handle_t mr_dev_handle = (dev_handle_t)IPC_GET_ARG4(*request);
+	int res;
+	ipcarg_t rc;
+
+	ipc_call_t call;
+	ipc_callid_t callid;
+
+	/* accept the phone */
+	callid = async_get_call(&call);
+	int mountee_phone = (int)IPC_GET_ARG1(call);
+	if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
+	    mountee_phone < 0) {
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+	ipc_answer_0(callid, EOK);	/* acknowledge the mountee_phone */
+	
+	res = ipc_data_write_receive(&callid, NULL);
+	if (!res) {
+		ipc_hangup(mountee_phone);
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+
+	fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index);
+	if (!fn) {
+		ipc_hangup(mountee_phone);
+		ipc_answer_0(callid, ENOENT);
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+
+	if (fn->mp_data.mp_active) {
+		ipc_hangup(mountee_phone);
+		ops->node_put(fn);
+		ipc_answer_0(callid, EBUSY);
+		ipc_answer_0(rid, EBUSY);
+		return;
+	}
+
+	rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
+	if (rc != 0) {
+		ipc_hangup(mountee_phone);
+		ops->node_put(fn);
+		ipc_answer_0(callid, rc);
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	ipc_call_t answer;
+	aid_t msg = async_send_1(mountee_phone, VFS_MOUNTED, mr_dev_handle,
+	    &answer);
+	ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+	async_wait_for(msg, &rc);
+	
+	if (rc == EOK) {
+		fn->mp_data.mp_active = true;
+		fn->mp_data.fs_handle = mr_fs_handle;
+		fn->mp_data.dev_handle = mr_dev_handle;
+		fn->mp_data.phone = mountee_phone;
+	}
+	/*
+	 * Do not release the FS node so that it stays in memory.
+	 */
+	ipc_answer_0(rid, rc);
+}
+
 /** Lookup VFS triplet by name in the file system name space.
  *
@@ -138,6 +217,7 @@
     ipc_call_t *request)
 {
-	unsigned next = IPC_GET_ARG1(*request);
+	unsigned first = IPC_GET_ARG1(*request);
 	unsigned last = IPC_GET_ARG2(*request);
+	unsigned next = first;
 	dev_handle_t dev_handle = IPC_GET_ARG3(*request);
 	int lflag = IPC_GET_ARG4(*request);
@@ -152,4 +232,12 @@
 	fs_node_t *cur = ops->root_get(dev_handle);
 	fs_node_t *tmp = NULL;
+
+	if (cur->mp_data.mp_active) {
+		ipc_forward_slow(rid, cur->mp_data.phone, VFS_LOOKUP,
+		    next, last, cur->mp_data.dev_handle, lflag, index,
+		    IPC_FF_ROUTE_FROM_ME);
+		ops->node_put(cur);
+		return;
+	}
 
 	if (ops->plb_get_char(next) == '/')
@@ -175,4 +263,19 @@
 		/* match the component */
 		tmp = ops->match(cur, component);
+		if (tmp && tmp->mp_data.mp_active) {
+			if (next > last)
+				next = last = first;
+			else
+				next--;
+				
+			ipc_forward_slow(rid, tmp->mp_data.phone, VFS_LOOKUP,
+			    next, last, tmp->mp_data.dev_handle, lflag, index,
+			    IPC_FF_ROUTE_FROM_ME);
+			ops->node_put(cur);
+			ops->node_put(tmp);
+			if (par)
+				ops->node_put(par);
+			return;
+		}
 
 		/* handle miss: match amongst siblings */
Index: uspace/lib/libfs/libfs.h
===================================================================
--- uspace/lib/libfs/libfs.h	(revision cf95bc0cb5a4fbbb4ff76dd9072c26acb9072d93)
+++ uspace/lib/libfs/libfs.h	(revision fc0110df7ea7e14571f47118909114c5dbbbd866)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2007 Jakub Jermar
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -43,5 +43,13 @@
 
 typedef struct {
-	void *data;	/**< Data of the file system implementation. */
+	bool mp_active;
+	int phone;
+	fs_handle_t fs_handle;
+	dev_handle_t dev_handle;
+} mp_data_t;
+
+typedef struct {
+	mp_data_t mp_data;	/**< Mount point info. */
+	void *data;		/**< Data of the file system implementation. */
 } fs_node_t;
 
@@ -72,4 +80,7 @@
 extern int fs_register(int, fs_reg_t *, vfs_info_t *, async_client_conn_t);
 
+extern void fs_node_initialize(fs_node_t *);
+
+extern void libfs_mount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
 
