Index: uspace/lib/libc/generic/async.c
===================================================================
--- uspace/lib/libc/generic/async.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/lib/libc/generic/async.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -1345,20 +1345,23 @@
 }
 
-/** Wrapper for receiving blobs via the async_data_write_*
+/** Wrapper for receiving binary data via the async_data_write_*
  *
  * This wrapper only makes it more comfortable to use async_data_write_*
  * functions to receive blobs.
  *
- * @param blob     Pointer to data pointer (which should be later disposed
- *                 by free()). If the operation fails, the pointer is not
- *                 touched.
- * @param max_size Maximum size (in bytes) of the blob to receive. 0 means
- *                 no limit.
- * @param received If not NULL, the size of the received data is stored here.
+ * @param data       Pointer to data pointer (which should be later disposed
+ *                   by free()). If the operation fails, the pointer is not
+ *                   touched.
+ * @param max_size   Maximum size (in bytes) of the data to receive. 0 means
+ *                   no limit.
+ * @param granulariy If non-zero, then the size of the received data has to
+ *                   be divisible by this value.
+ * @param received   If not NULL, the size of the received data is stored here.
  *
  * @return Zero on success or a value from @ref errno.h on failure.
  *
  */
-int async_data_blob_receive(char **blob, const size_t max_size, size_t *received)
+int async_data_receive(void **data, const size_t max_size,
+    const size_t granularity, size_t *received)
 {
 	ipc_callid_t callid;
@@ -1374,17 +1377,22 @@
 	}
 	
-	char *data = (char *) malloc(size);
-	if (data == NULL) {
+	if ((granularity > 0) && ((size % granularity) != 0)) {
+		ipc_answer_0(callid, EINVAL);
+		return EINVAL;
+	}
+	
+	void *_data = malloc(size);
+	if (_data == NULL) {
 		ipc_answer_0(callid, ENOMEM);
 		return ENOMEM;
 	}
 	
-	int rc = async_data_write_finalize(callid, data, size);
+	int rc = async_data_write_finalize(callid, _data, size);
 	if (rc != EOK) {
-		free(data);
+		free(_data);
 		return rc;
 	}
 	
-	*blob = data;
+	*data = _data;
 	if (received != NULL)
 		*received = size;
@@ -1403,9 +1411,10 @@
  * @param max_size Maximum size (in bytes) of the string to receive. 0 means
  *                 no limit.
+ * @param received If not NULL, the size of the received data is stored here.
  *
  * @return Zero on success or a value from @ref errno.h on failure.
  *
  */
-int async_data_string_receive(char **str, const size_t max_size)
+int async_string_receive(char **str, const size_t max_size, size_t *received)
 {
 	ipc_callid_t callid;
@@ -1435,4 +1444,7 @@
 	data[size] = 0;
 	*str = data;
+	if (received != NULL)
+		*received = size;
+	
 	return EOK;
 }
Index: uspace/lib/libc/generic/clipboard.c
===================================================================
--- uspace/lib/libc/generic/clipboard.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/lib/libc/generic/clipboard.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -84,5 +84,5 @@
 		clip_connect();
 		
-		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_BLOB, NULL);
+		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
 		ipcarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
 		if (rc != EOK) {
@@ -139,5 +139,5 @@
 			*str = sbuf;
 			return EOK;
-		case CLIPBOARD_TAG_BLOB:
+		case CLIPBOARD_TAG_DATA:
 			sbuf = malloc(size + 1);
 			if (sbuf == NULL)
Index: uspace/lib/libc/include/async.h
===================================================================
--- uspace/lib/libc/include/async.h	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/lib/libc/include/async.h	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -284,6 +284,6 @@
 extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
 
-extern int async_data_blob_receive(char **, const size_t, size_t *);
-extern int async_data_string_receive(char **, const size_t);
+extern int async_data_receive(void **, const size_t, const size_t, size_t *);
+extern int async_string_receive(char **, const size_t, size_t *);
 
 #endif
Index: uspace/lib/libc/include/ipc/clipboard.h
===================================================================
--- uspace/lib/libc/include/ipc/clipboard.h	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/lib/libc/include/ipc/clipboard.h	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -46,5 +46,5 @@
 typedef enum {
 	CLIPBOARD_TAG_NONE,
-	CLIPBOARD_TAG_BLOB
+	CLIPBOARD_TAG_DATA
 } clipboard_tag_t;
 
Index: uspace/srv/clip/clip.c
===================================================================
--- uspace/srv/clip/clip.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/clip/clip.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -64,6 +64,6 @@
 		ipc_answer_0(rid, EOK);
 		break;
-	case CLIPBOARD_TAG_BLOB:
-		rc = async_data_blob_receive(&data, 0, &size);
+	case CLIPBOARD_TAG_DATA:
+		rc = async_data_receive(&data, 0, 0, &size);
 		if (rc != EOK) {
 			ipc_answer_0(rid, rc);
@@ -78,5 +78,5 @@
 		clip_data = data;
 		clip_size = size;
-		clip_tag = CLIPBOARD_TAG_BLOB;
+		clip_tag = CLIPBOARD_TAG_DATA;
 		
 		fibril_mutex_unlock(&clip_mtx);
@@ -97,5 +97,5 @@
 	/* Check for clipboard data tag compatibility */
 	switch (IPC_GET_ARG1(*request)) {
-	case CLIPBOARD_TAG_BLOB:
+	case CLIPBOARD_TAG_DATA:
 		if (!async_data_read_receive(&callid, &size)) {
 			ipc_answer_0(callid, EINVAL);
@@ -104,6 +104,6 @@
 		}
 		
-		if (clip_tag != CLIPBOARD_TAG_BLOB) {
-			/* So far we only understand BLOB */
+		if (clip_tag != CLIPBOARD_TAG_DATA) {
+			/* So far we only understand binary data */
 			ipc_answer_0(callid, EOVERFLOW);
 			ipc_answer_0(rid, EOVERFLOW);
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/devmap/devmap.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -396,5 +396,5 @@
 	 * Get driver name
 	 */
-	int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN);
+	int rc = async_string_receive(&driver->name, DEVMAP_NAME_MAXLEN, NULL);
 	if (rc != EOK) {
 		free(driver);
@@ -510,5 +510,5 @@
 	/* Get fqdn */
 	char *fqdn;
-	int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
+	int rc = async_string_receive(&fqdn, DEVMAP_NAME_MAXLEN, NULL);
 	if (rc != EOK) {
 		free(device);
@@ -622,5 +622,5 @@
 	
 	/* Get fqdn */
-	int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN);
+	int rc = async_string_receive(&fqdn, DEVMAP_NAME_MAXLEN, NULL);
 	if (rc != EOK) {
 		ipc_answer_0(iid, rc);
@@ -683,5 +683,5 @@
 	
 	/* Get device name */
-	int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN);
+	int rc = async_string_receive(&name, DEVMAP_NAME_MAXLEN, NULL);
 	if (rc != EOK) {
 		ipc_answer_0(iid, rc);
Index: uspace/srv/fs/devfs/devfs_ops.c
===================================================================
--- uspace/srv/fs/devfs/devfs_ops.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/fs/devfs/devfs_ops.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -419,5 +419,5 @@
 	
 	/* Accept the mount options */
-	ipcarg_t retval = async_data_string_receive(&opts, 0);
+	ipcarg_t retval = async_string_receive(&opts, 0, NULL);
 	if (retval != EOK) {
 		ipc_answer_0(rid, retval);
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -974,27 +974,13 @@
 	uint16_t bps;
 	uint16_t rde;
-	int rc;
-
-	/* accept the mount options */
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *opts = malloc(size + 1);
-	if (!opts) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
-		free(opts);
-		return;
-	}
-	opts[size] = '\0';
+	
+	/* Accept the mount options */
+	char *opts;
+	int rc = async_string_receive(&opts, 0, NULL);
+	
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 
 	/* Check for option enabling write through. */
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -439,27 +439,13 @@
 {
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
-	int rc;
-
-	/* accept the mount options */
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *opts = malloc(size + 1);
-	if (!opts) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	ipcarg_t retval = async_data_write_finalize(callid, opts, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
-		free(opts);
-		return;
-	}
-	opts[size] = '\0';
+	
+	/* Accept the mount options */
+	char *opts;
+	int rc = async_string_receive(&opts, 0, NULL);
+	
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 
 	/* Initialize TMPFS instance. */
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/hid/console/console.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -475,20 +475,12 @@
 static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
+	void *buf;
 	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
+	int rc = async_data_receive(&buf, 0, 0, &size);
+	
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
 		return;
 	}
-	
-	char *buf = (char *) malloc(size);
-	if (buf == NULL) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	(void) async_data_write_finalize(callid, buf, size);
 	
 	async_serialize_start();
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/loader/main.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -125,24 +125,15 @@
 static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t len;
-	
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	cwd = malloc(len + 1);
-	if (!cwd) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, cwd, len);
-	cwd[len] = '\0';
-	
-	ipc_answer_0(rid, EOK);
+	char *buf;
+	int rc = async_string_receive(&buf, 0, NULL);
+	
+	if (rc == EOK) {
+		if (cwd != NULL)
+			free(cwd);
+		
+		cwd = buf;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -154,31 +145,15 @@
 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t len;
-	char *name_buf;
-	
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	name_buf = malloc(len + 1);
-	if (!name_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, name_buf, len);
-	ipc_answer_0(rid, EOK);
-	
-	if (pathname != NULL) {
-		free(pathname);
-		pathname = NULL;
-	}
-	
-	name_buf[len] = '\0';
-	pathname = name_buf;
+	char *buf;
+	int rc = async_string_receive(&buf, 0, NULL);
+	
+	if (rc == EOK) {
+		if (pathname != NULL)
+			free(pathname);
+		
+		pathname = buf;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -190,73 +165,60 @@
 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
-	size_t buf_size, arg_size;
-	char *p;
-	int n;
-	
-	if (!async_data_write_receive(&callid, &buf_size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if (arg_buf != NULL) {
-		free(arg_buf);
-		arg_buf = NULL;
-	}
-	
-	if (argv != NULL) {
-		free(argv);
-		argv = NULL;
-	}
-	
-	arg_buf = malloc(buf_size + 1);
-	if (!arg_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, arg_buf, buf_size);
-	
-	arg_buf[buf_size] = '\0';
-	
-	/*
-	 * Count number of arguments
-	 */
-	p = arg_buf;
-	n = 0;
-	while (p < arg_buf + buf_size) {
-		arg_size = str_size(p);
-		p = p + arg_size + 1;
-		++n;
-	}
-	
-	/* Allocate argv */
-	argv = malloc((n + 1) * sizeof(char *));
-	
-	if (argv == NULL) {
-		free(arg_buf);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-
-	/*
-	 * Fill argv with argument pointers
-	 */
-	p = arg_buf;
-	n = 0;
-	while (p < arg_buf + buf_size) {
-		argv[n] = p;
-		
-		arg_size = str_size(p);
-		p = p + arg_size + 1;
-		++n;
-	}
-	
-	argc = n;
-	argv[n] = NULL;
-
-	ipc_answer_0(rid, EOK);
+	char *buf;
+	size_t buf_size;
+	int rc = async_string_receive(&buf, 0, &buf_size);
+	
+	if (rc == EOK) {
+		/*
+		 * Count number of arguments
+		 */
+		char *cur = buf;
+		int count = 0;
+		
+		while (cur < buf + buf_size) {
+			size_t arg_size = str_size(cur);
+			cur += arg_size + 1;
+			count++;
+		}
+		
+		/*
+		 * Allocate new argv
+		 */
+		char **_argv = (char **) malloc((count + 1) * sizeof(char *));
+		if (_argv == NULL) {
+			free(buf);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+		
+		/*
+		 * Fill the new argv with argument pointers
+		 */
+		cur = buf;
+		count = 0;
+		while (cur < buf + buf_size) {
+			_argv[count] = cur;
+			
+			size_t arg_size = str_size(cur);
+			cur += arg_size + 1;
+			count++;
+		}
+		_argv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (arg_buf != NULL)
+			free(arg_buf);
+		
+		if (argv != NULL)
+			free(argv);
+		
+		argc = count;
+		arg_buf = buf;
+		argv = _argv;
+	}
+	
+	ipc_answer_0(rid, rc);
 }
 
@@ -268,57 +230,43 @@
 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
 {
-	ipc_callid_t callid;
+	void *buf;
 	size_t buf_size;
-	if (!async_data_write_receive(&callid, &buf_size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if ((buf_size % sizeof(fdi_node_t)) != 0) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	if (fil_buf != NULL) {
-		free(fil_buf);
-		fil_buf = NULL;
-	}
-	
-	if (filv != NULL) {
-		free(filv);
-		filv = NULL;
-	}
-	
-	fil_buf = malloc(buf_size);
-	if (!fil_buf) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	async_data_write_finalize(callid, fil_buf, buf_size);
-	
-	int count = buf_size / sizeof(fdi_node_t);
-	
-	/* Allocate filvv */
-	filv = malloc((count + 1) * sizeof(fdi_node_t *));
-	
-	if (filv == NULL) {
-		free(fil_buf);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	/*
-	 * Fill filv with argument pointers
-	 */
-	int i;
-	for (i = 0; i < count; i++)
-		filv[i] = &fil_buf[i];
-	
-	filc = count;
-	filv[count] = NULL;
+	int rc = async_data_receive(&buf, 0, sizeof(fdi_node_t), &buf_size);
+	
+	if (rc == EOK) {
+		int count = buf_size / sizeof(fdi_node_t);
+		
+		/*
+		 * Allocate new filv
+		 */
+		fdi_node_t **_filv = (fdi_node_t *) malloc((count + 1) * sizeof(fdi_node_t *));
+		if (_filv == NULL) {
+			free(buf);
+			ipc_answer_0(rid, ENOMEM);
+			return;
+		}
+		
+		/*
+		 * Fill the new filv with argument pointers
+		 */
+		int i;
+		for (i = 0; i < count; i++)
+			_filv[i] = &((fdi_node_t *) buf)[i];
+		
+		_filv[count] = NULL;
+		
+		/*
+		 * Copy temporary data to global variables
+		 */
+		if (fil_buf != NULL)
+			free(fil_buf);
+		
+		if (filv != NULL)
+			free(filv);
+		
+		filc = count;
+		fil_buf = (fdi_node_t *) buf;
+		filv = _filv;
+	}
 	
 	ipc_answer_0(rid, EOK);
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 28be7fa0fa0ad68be08aa62293dc4d0e38e07dca)
+++ uspace/srv/vfs/vfs_ops.c	(revision 472c09d5893ee3d91337e6bd2fdda63fdbe11301)
@@ -266,118 +266,33 @@
 	
 	/* We want the client to send us the mount point. */
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	/* Check whether size is reasonable wrt. the mount point. */
-	if ((size < 1) || (size > MAX_PATH_LEN)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	/* Allocate buffer for the mount point data being received. */
-	char *mp = malloc(size + 1);
-	if (!mp) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	/* Deliver the mount point. */
-	ipcarg_t retval = async_data_write_finalize(callid, mp, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
+	char *mp;
+	int rc = async_string_receive(&mp, MAX_PATH_LEN, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	/* Now we expect to receive the mount options. */
+	char *opts;
+	rc = async_string_receive(&opts, MAX_MNTOPTS_LEN, NULL);
+	if (rc != EOK) {
 		free(mp);
-		return;
-	}
-	mp[size] = '\0';
-	
-	/* Now we expect to receive the mount options. */
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		return;
-	}
-
-	/* Check the offered options size. */
-	if (size > MAX_MNTOPTS_LEN) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		return;
-	}
-
-	/* Allocate buffer for the mount options. */
-	char *opts = (char *) malloc(size + 1);
-	if (!opts) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		free(mp);
-		return;
-	}
-
-	/* Deliver the mount options. */
-	retval = async_data_write_finalize(callid, opts, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	/*
+	 * Now, we expect the client to send us data with the name of the file
+	 * system.
+	 */
+	char *fs_name;
+	rc = async_string_receive(&fs_name, FS_NAME_MAXLEN, NULL);
+	if (rc != EOK) {
 		free(mp);
 		free(opts);
-		return;
-	}
-	opts[size] = '\0';
-	
-	/*
-	 * Now, we expect the client to send us data with the name of the file
-	 * system.
-	 */
-	if (!async_data_write_receive(&callid, &size)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		free(opts);
-		return;
-	}
-	
-	/*
-	 * Don't receive more than is necessary for storing a full file system
-	 * name.
-	 */
-	if ((size < 1) || (size > FS_NAME_MAXLEN)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(mp);
-		free(opts);
-		return;
-	}
-	
-	/*
-	 * Allocate buffer for file system name.
-	 */
-	char *fs_name = (char *) malloc(size + 1);
-	if (fs_name == NULL) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		free(mp);
-		free(opts);
-		return;
-	}
-	
-	/* Deliver the file system name. */
-	retval = async_data_write_finalize(callid, fs_name, size);
-	if (retval != EOK) {
-		ipc_answer_0(rid, retval);
-		free(mp);
-		free(opts);
-		free(fs_name);
-		return;
-	}
-	fs_name[size] = '\0';
-
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
 	/*
 	 * Wait for IPC_M_PING so that we can return an error if we don't know
@@ -385,5 +300,5 @@
 	 */
 	ipc_call_t data;
-	callid = async_get_call(&data);
+	ipc_callid_t callid = async_get_call(&data);
 	if (IPC_GET_METHOD(data) != IPC_M_PING) {
 		ipc_answer_0(callid, ENOTSUP);
@@ -442,5 +357,5 @@
 	 * Receive the mount point path.
 	 */
-	rc = async_data_string_receive(&mp, MAX_PATH_LEN);
+	rc = async_string_receive(&mp, MAX_PATH_LEN, NULL);
 	if (rc != EOK)
 		ipc_answer_0(rid, rc);
@@ -606,25 +521,10 @@
 		lflag |= L_EXCLUSIVE;
 	
-	ipc_callid_t callid;
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
+	char *path;
+	int rc = async_string_receive(&path, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	
 	/*
@@ -1120,26 +1020,12 @@
 void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
 {
-	size_t len;
+	char *path;
+	int rc = async_string_receive(&path, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
 	ipc_callid_t callid;
-
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
-
 	if (!async_data_read_receive(&callid, NULL)) {
 		free(path);
@@ -1187,27 +1073,12 @@
 {
 	int mode = IPC_GET_ARG1(*request);
-
-	size_t len;
-	ipc_callid_t callid;
-
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
-
+	
+	char *path;
+	int rc = async_string_receive(&path, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
 	/* Ignore mode for now. */
 	(void) mode;
@@ -1224,26 +1095,11 @@
 {
 	int lflag = IPC_GET_ARG1(*request);
-
-	size_t len;
-	ipc_callid_t callid;
-
-	if (!async_data_write_receive(&callid, &len)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *path = malloc(len + 1);
-	if (!path) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	int rc;
-	if ((rc = async_data_write_finalize(callid, path, len))) {
-		ipc_answer_0(rid, rc);
-		free(path);
-		return;
-	}
-	path[len] = '\0';
+	
+	char *path;
+	int rc = async_string_receive(&path, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
 	
 	fibril_rwlock_write_lock(&namespace_rwlock);
@@ -1274,52 +1130,27 @@
 void vfs_rename(ipc_callid_t rid, ipc_call_t *request)
 {
-	size_t olen, nlen;
-	ipc_callid_t callid;
-	int rc;
-
 	/* Retrieve the old path. */
-	if (!async_data_write_receive(&callid, &olen)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		return;
-	}
-	char *old = malloc(olen + 1);
-	if (!old) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		return;
-	}
-	if ((rc = async_data_write_finalize(callid, old, olen))) {
-		ipc_answer_0(rid, rc);
+	char *old;
+	int rc = async_string_receive(&old, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	/* Retrieve the new path. */
+	char *new;
+	rc = async_string_receive(&new, 0, NULL);
+	if (rc != EOK) {
 		free(old);
-		return;
-	}
-	old[olen] = '\0';
-	
-	/* Retrieve the new path. */
-	if (!async_data_write_receive(&callid, &nlen)) {
-		ipc_answer_0(callid, EINVAL);
-		ipc_answer_0(rid, EINVAL);
-		free(old);
-		return;
-	}
-	char *new = malloc(nlen + 1);
-	if (!new) {
-		ipc_answer_0(callid, ENOMEM);
-		ipc_answer_0(rid, ENOMEM);
-		free(old);
-		return;
-	}
-	if ((rc = async_data_write_finalize(callid, new, nlen))) {
-		ipc_answer_0(rid, rc);
-		free(old);
-		free(new);
-		return;
-	}
-	new[nlen] = '\0';
-
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	
+	size_t olen;
+	size_t nlen;
 	char *oldc = canonify(old, &olen);
 	char *newc = canonify(new, &nlen);
-	if (!oldc || !newc) {
+	
+	if ((!oldc) || (!newc)) {
 		ipc_answer_0(rid, EINVAL);
 		free(old);
@@ -1327,6 +1158,8 @@
 		return;
 	}
+	
 	oldc[olen] = '\0';
 	newc[nlen] = '\0';
+	
 	if ((!str_lcmp(newc, oldc, str_length(oldc))) &&
 	    ((newc[str_length(oldc)] == '/') ||
@@ -1349,4 +1182,5 @@
 	vfs_lookup_res_t new_par_lr;
 	fibril_rwlock_write_lock(&namespace_rwlock);
+	
 	/* Lookup the node belonging to the old file name. */
 	rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL);
@@ -1358,4 +1192,5 @@
 		return;
 	}
+	
 	vfs_node_t *old_node = vfs_node_get(&old_lr);
 	if (!old_node) {
@@ -1366,4 +1201,5 @@
 		return;
 	}
+	
 	/* Determine the path to the parent of the node with the new name. */
 	char *parentc = str_dup(newc);
@@ -1375,4 +1211,5 @@
 		return;
 	}
+	
 	char *lastsl = str_rchr(parentc + 1, '/');
 	if (lastsl)
@@ -1380,4 +1217,5 @@
 	else
 		parentc[1] = '\0';
+	
 	/* Lookup parent of the new file name. */
 	rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL);
@@ -1390,4 +1228,5 @@
 		return;
 	}
+	
 	/* Check whether linking to the same file system instance. */
 	if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) ||
@@ -1399,7 +1238,9 @@
 		return;
 	}
+	
 	/* Destroy the old link for the new name. */
 	vfs_node_t *new_node = NULL;
 	rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL);
+	
 	switch (rc) {
 	case ENOENT:
@@ -1426,4 +1267,5 @@
 		return;
 	}
+	
 	/* Create the new link for the new name. */
 	rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index);
@@ -1437,7 +1279,9 @@
 		return;
 	}
+	
 	fibril_mutex_lock(&nodes_mutex);
 	old_node->lnkcnt++;
 	fibril_mutex_unlock(&nodes_mutex);
+	
 	/* Destroy the link for the old name. */
 	rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL);
@@ -1452,4 +1296,5 @@
 		return;
 	}
+	
 	fibril_mutex_lock(&nodes_mutex);
 	old_node->lnkcnt--;
@@ -1457,6 +1302,8 @@
 	fibril_rwlock_write_unlock(&namespace_rwlock);
 	vfs_node_put(old_node);
+	
 	if (new_node)
 		vfs_node_put(new_node);
+	
 	free(old);
 	free(new);
