Index: uspace/lib/libfs/libfs.c
===================================================================
--- uspace/lib/libfs/libfs.c	(revision a61d1fc3aa43e7a55cd4864d7eb1669c9e1f12f4)
+++ uspace/lib/libfs/libfs.c	(revision c544c5d07c2bd7b5301e09b4a820744b9010991c)
@@ -37,4 +37,5 @@
 #include "libfs.h" 
 #include "../../srv/vfs/vfs.h"
+#include "../../srv/rd/rd.h"
 #include <errno.h>
 #include <async.h>
@@ -331,7 +332,4 @@
 }
 
-#define RD_BASE		1024	// FIXME
-#define RD_READ_BLOCK	(RD_BASE + 1)
-
 /** Read data from a block device.
  *
Index: uspace/srv/rd/rd.c
===================================================================
--- uspace/srv/rd/rd.c	(revision a61d1fc3aa43e7a55cd4864d7eb1669c9e1f12f4)
+++ uspace/srv/rd/rd.c	(revision c544c5d07c2bd7b5301e09b4a820744b9010991c)
@@ -82,44 +82,22 @@
 	int retval;
 	void *fs_va = NULL;
-	ipcarg_t offset;
+	off_t offset;
+	size_t block_size;
+	size_t maxblock_size;
 
 	/*
-	 * We allocate VA for communication per connection.
-	 * This allows us to potentionally have more clients and work
-	 * concurrently.
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
 	 */
-	fs_va = as_get_mappable_page(ALIGN_UP(BLOCK_SIZE, PAGE_SIZE));
-	if (!fs_va) {
-		/*
-		 * Hang up the phone if we cannot proceed any further.
-		 * This is the answer to the call that opened the connection.
-		 */
-		ipc_answer_0(iid, EHANGUP);
-		return;
-	} else {
-		/*
-		 * Answer the first IPC_M_CONNECT_ME_TO call.
-		 * Return supported block size as ARG1.
-		 */
-		ipc_answer_1(iid, EOK, BLOCK_SIZE);
-	}
+	ipc_answer_0(iid, EOK);
 
 	/*
 	 * Now we wait for the client to send us its communication as_area.
 	 */
-	size_t size;
 	int flags;
-	if (ipc_share_out_receive(&callid, &size, &flags)) {
-		if (size >= BLOCK_SIZE) {
-			/*
-			 * The client sends an as_area that can absorb the whole
-			 * block.
-			 */
+	if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
+		fs_va = as_get_mappable_page(maxblock_size);
+		if (fs_va) {
 			(void) ipc_share_out_finalize(callid, fs_va);
 		} else {
-			/*
-			 * The client offered as_area too small.
-			 * Close the connection.
-			 */
 			ipc_answer_0(callid, EHANGUP);
 			return;		
@@ -147,5 +125,13 @@
 		case RD_READ_BLOCK:
 			offset = IPC_GET_ARG1(call);
-			if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) {
+			block_size = IPC_GET_ARG2(call);
+			if (block_size > maxblock_size) {
+				/*
+				 * Maximum block size exceeded.
+				 */
+				retval = ELIMIT;
+				break;
+			}
+			if (offset * block_size > rd_size - block_size) {
 				/*
 				 * Reading past the end of the device.
@@ -155,5 +141,5 @@
 			}
 			futex_down(&rd_futex);
-			memcpy(fs_va, rd_addr + offset * BLOCK_SIZE, BLOCK_SIZE);
+			memcpy(fs_va, rd_addr + offset * block_size, block_size);
 			futex_up(&rd_futex);
 			retval = EOK;
@@ -161,5 +147,13 @@
 		case RD_WRITE_BLOCK:
 			offset = IPC_GET_ARG1(call);
-			if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) {
+			block_size = IPC_GET_ARG2(call);
+			if (block_size > maxblock_size) {
+				/*
+				 * Maximum block size exceeded.
+				 */
+				retval = ELIMIT;
+				break;
+			}
+			if (offset * block_size > rd_size - block_size) {
 				/*
 				 * Writing past the end of the device.
@@ -169,5 +163,5 @@
 			}
 			futex_up(&rd_futex);
-			memcpy(rd_addr + offset * BLOCK_SIZE, fs_va, BLOCK_SIZE);
+			memcpy(rd_addr + offset * block_size, fs_va, block_size);
 			futex_down(&rd_futex);
 			retval = EOK;
Index: uspace/srv/rd/rd.h
===================================================================
--- uspace/srv/rd/rd.h	(revision a61d1fc3aa43e7a55cd4864d7eb1669c9e1f12f4)
+++ uspace/srv/rd/rd.h	(revision c544c5d07c2bd7b5301e09b4a820744b9010991c)
@@ -44,6 +44,4 @@
 #define RD_RD_H_
 
-#define BLOCK_SIZE	1024	/**< Working block size */
-
 #define RD_BASE		1024
 #define	RD_READ_BLOCK	(RD_BASE + 1)	/**< Method for reading block. */
