Index: uspace/srv/vfs/Makefile
===================================================================
--- uspace/srv/vfs/Makefile	(revision ebd9392cad002ffd2934826bc163d1b00508af24)
+++ uspace/srv/vfs/Makefile	(revision b3cd9eb53290f21cd8d641b59597ef033013237e)
@@ -49,4 +49,5 @@
 	vfs_mount.c \
 	vfs_open.c \
+	vfs_read.c \
 	vfs_unlink.c
 
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision ebd9392cad002ffd2934826bc163d1b00508af24)
+++ uspace/srv/vfs/vfs.c	(revision b3cd9eb53290f21cd8d641b59597ef033013237e)
@@ -95,8 +95,10 @@
 			vfs_open(callid, &call);
 			break;
+		case VFS_READ:
+			vfs_read(callid, &call);
+			break;
 		case VFS_UNMOUNT:
 		case VFS_CREATE:
 		case VFS_CLOSE:
-		case VFS_READ:
 		case VFS_WRITE:
 		case VFS_SEEK:
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision ebd9392cad002ffd2934826bc163d1b00508af24)
+++ uspace/srv/vfs/vfs.h	(revision b3cd9eb53290f21cd8d641b59597ef033013237e)
@@ -199,4 +199,5 @@
 extern void vfs_mount(ipc_callid_t, ipc_call_t *);
 extern void vfs_open(ipc_callid_t, ipc_call_t *);
+extern void vfs_read(ipc_callid_t, ipc_call_t *);
 
 #endif
Index: uspace/srv/vfs/vfs_read.c
===================================================================
--- uspace/srv/vfs/vfs_read.c	(revision b3cd9eb53290f21cd8d641b59597ef033013237e)
+++ uspace/srv/vfs/vfs_read.c	(revision b3cd9eb53290f21cd8d641b59597ef033013237e)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */ 
+
+/**
+ * @file	vfs_read.c
+ * @brief
+ */
+
+#include "vfs.h"
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+void vfs_read(ipc_callid_t rid, ipc_call_t *request)
+{
+
+	/*
+	 * The following code strongly depends on the fact that the files data
+	 * structure can be only accessed by a single fibril and all file
+	 * operations are serialized (i.e. the reads and writes cannot
+	 * interleave and a file cannot be closed while it is being read).
+	 *
+	 * Additional synchronization needs to be added once table table of
+	 * open files supports parallel access!
+	 */
+
+	/*
+	 * Because we don't support the receive analogy of IPC_M_DATA_SEND,
+	 * VFS_READ is emulutating its behavior via sharing an address space
+	 * area.
+	 */
+
+	int fd = IPC_GET_ARG1(*request);
+
+	/*
+	 * Lookup the file structure corresponding to the file descriptor.
+	 */
+	vfs_file_t *file = vfs_file_get(fd);
+	if (!file) {
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+
+	/*
+	 * Now we need to receive a call with client's address space area.
+	 */
+	ipc_callid_t callid;
+	ipc_call_t call;
+	callid = async_get_call(&call);
+	if (IPC_GET_METHOD(call) != IPC_M_AS_AREA_SEND) {
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+
+	int fs_phone = vfs_grab_phone(file->node->fs_handle);	
+	
+	/*
+	 * Make a VFS_READ request at the destination FS server.
+	 */
+	aid_t msg;
+	msg = async_send_3(fs_phone, VFS_READ, file->node->dev_handle,
+	    file->node->index, file->pos, NULL);
+	
+	/*
+	 * Forward the address space area offer to the destination FS server.
+	 * The call will be routed as if sent by ourselves.
+	 */
+	ipc_forward_fast(callid, fs_phone, IPC_GET_METHOD(call),
+	    IPC_GET_ARG1(call), IPC_FF_ROUTE_FROM_ME);
+
+	vfs_release_phone(fs_phone);
+
+	/*
+	 * Wait for reply from the FS server.
+	 */
+	ipcarg_t rc;
+	async_wait_for(msg, &rc);
+
+	/*
+	 * FS server's reply is the final result of the whole operation we
+	 * return to the client.
+	 */
+	ipc_answer_0(rid, rc);
+}
+
+/**
+ * @}
+ */ 
