Index: uspace/lib/libc/generic/ipc.c
===================================================================
--- uspace/lib/libc/generic/ipc.c	(revision a55d5f9fbe9f149843781206c69705643f929991)
+++ uspace/lib/libc/generic/ipc.c	(revision a92da0ab969fe27e89dc49e17eb3cceb2aabcbb7)
@@ -690,5 +690,6 @@
  * @param callid	Storage where the hash of the IPC_M_DATA_READ call will
  * 			be stored.
- * @param size		Storage where the maximum size will be stored.
+ * @param size		Storage where the maximum size will be stored. Can be
+ *			NULL.
  *
  * @return		Non-zero on success, zero on failure.
@@ -703,6 +704,6 @@
 	if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)
 		return 0;
-	assert(size);
-	*size = (size_t) IPC_GET_ARG2(data);
+	if (size)
+		*size = (size_t) IPC_GET_ARG2(data);
 	return 1;
 }
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision a55d5f9fbe9f149843781206c69705643f929991)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision a92da0ab969fe27e89dc49e17eb3cceb2aabcbb7)
@@ -283,5 +283,4 @@
 	unsigned long index = IPC_GET_ARG2(*request);
 	off_t pos = IPC_GET_ARG3(*request);
-	size_t size = IPC_GET_ARG4(*request);
 
 	/*
@@ -298,10 +297,9 @@
 
 	/*
-	 * Receive the communication area.
+	 * Receive the read request.
 	 */
 	ipc_callid_t callid;
-	ipc_call_t call;
-	callid = async_get_call(&call);
-	if (IPC_GET_METHOD(call) != IPC_M_AS_AREA_SEND) {
+	size_t size;
+	if (!ipc_data_read_receive(&callid, size)) {
 		ipc_answer_0(callid, EINVAL);	
 		ipc_answer_0(rid, EINVAL);
@@ -309,25 +307,6 @@
 	}
 
-	int flags = IPC_GET_ARG3(call);
-	if (!(flags & AS_AREA_WRITE)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	size_t sz = IPC_GET_ARG2(call);
-	uint8_t *buf = as_get_mappable_page(sz);
-	if (!buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	ipc_answer_1(callid, EOK, buf);		/* commit to share the area */
-
 	size_t bytes = max(0, min(dentry->size - pos, size));
-	memcpy(buf, dentry->data + pos, bytes);
-
-	(void) as_area_destroy(buf);
-
-	ipc_answer_1(rid, EOK, bytes);
+	(void) ipc_data_read_deliver(callid, dentry->data + pos, bytes);
 }
 
Index: uspace/srv/vfs/vfs_read.c
===================================================================
--- uspace/srv/vfs/vfs_read.c	(revision a55d5f9fbe9f149843781206c69705643f929991)
+++ uspace/srv/vfs/vfs_read.c	(revision a92da0ab969fe27e89dc49e17eb3cceb2aabcbb7)
@@ -54,12 +54,5 @@
 	 */
 
-	/*
-	 * 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);
-	size_t size = IPC_GET_ARG2(*request);
 
 	/*
@@ -73,10 +66,8 @@
 
 	/*
-	 * Now we need to receive a call with client's address space area.
+	 * Now we need to receive a call with client's IPC_M_DATA_READ request.
 	 */
 	ipc_callid_t callid;
-	ipc_call_t call;
-	callid = async_get_call(&call);
-	if (IPC_GET_METHOD(call) != IPC_M_AS_AREA_SEND) {
+	if (!ipc_data_read_receive(&callid, NULL)) {
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -91,13 +82,13 @@
 	aid_t msg;
 	ipc_call_t answer;
-	msg = async_send_4(fs_phone, VFS_READ, file->node->dev_handle,
-	    file->node->index, file->pos, size, &answer);
+	msg = async_send_3(fs_phone, VFS_READ, file->node->dev_handle,
+	    file->node->index, file->pos, &answer);
 	
 	/*
-	 * Forward the address space area offer to the destination FS server.
-	 * The call will be routed as if sent by ourselves.
+	 * Forward the IPC_M_DATA_READ request to the destination FS server.
+	 * The call will be routed as if sent by ourselves. Note that call
+	 * arguments are immutable in this case so we don't have to bother.
 	 */
-	ipc_forward_fast(callid, fs_phone, IPC_GET_METHOD(call),
-	    IPC_GET_ARG1(call), 0, IPC_FF_ROUTE_FROM_ME);
+	ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
 
 	vfs_release_phone(fs_phone);
