Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/app/init/init.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -46,4 +46,5 @@
 #include <macros.h>
 #include <console.h>
+#include <string.h>
 #include "init.h"
 #include "version.h"
@@ -52,7 +53,11 @@
 {
 	int rc = -1;
+	char *opts = "";
 	
+	if (str_cmp(fstype, "tmpfs") == 0)
+		opts = "restore";
+
 	while (rc < 0) {
-		rc = mount(fstype, "/", "initrd", IPC_FLAG_BLOCKING);
+		rc = mount(fstype, "/", "initrd", opts, IPC_FLAG_BLOCKING);
 		
 		switch (rc) {
Index: uspace/app/tester/vfs/vfs1.c
===================================================================
--- uspace/app/tester/vfs/vfs1.c	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/app/tester/vfs/vfs1.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -46,5 +46,5 @@
 	int rc;
 
-	rc = mount("tmpfs", "/", "nulldev0", 0);
+	rc = mount("tmpfs", "/", "nulldev0", "", 0);
 	switch (rc) {
 	case EOK:
Index: uspace/lib/libc/generic/vfs/vfs.c
===================================================================
--- uspace/lib/libc/generic/vfs/vfs.c	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/lib/libc/generic/vfs/vfs.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -156,5 +156,5 @@
 
 int mount(const char *fs_name, const char *mp, const char *dev,
-	const unsigned int flags)
+    const char *opts, const unsigned int flags)
 {
 	int res;
@@ -186,4 +186,13 @@
 	}
 	
+	rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		async_serialize_end();
+		futex_up(&vfs_phone_futex);
+		free(mpa);
+		return (int) rc;
+	}
+
 	rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
 	if (rc != EOK) {
Index: uspace/lib/libc/include/vfs/vfs.h
===================================================================
--- uspace/lib/libc/include/vfs/vfs.h	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/lib/libc/include/vfs/vfs.h	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -40,5 +40,5 @@
 extern char *absolutize(const char *, size_t *);
 
-extern int mount(const char *, const char *, const char *,
+extern int mount(const char *, const char *, const char *, const char *,
     const unsigned int flags);
 
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -756,4 +756,26 @@
 	int rc;
 
+	/* accept the mount options */
+	ipc_callid_t callid;
+	size_t size;
+	if (!ipc_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 = ipc_data_write_finalize(callid, opts, size);
+	if (retval != EOK) {
+		ipc_answer_0(rid, retval);
+		free(opts);
+		return;
+	}
+	opts[size] = '\0';
+
 	/* initialize libblock */
 	rc = block_init(dev_handle, BS_SIZE);
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -400,4 +400,26 @@
 	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 
+	/* accept the mount options */
+	ipc_callid_t callid;
+	size_t size;
+	if (!ipc_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 = ipc_data_write_finalize(callid, opts, size);
+	if (retval != EOK) {
+		ipc_answer_0(rid, retval);
+		free(opts);
+		return;
+	}
+	opts[size] = '\0';
+
 	/* Initialize TMPFS. */
 	if (!root && !tmpfs_init()) {
@@ -406,5 +428,5 @@
 	}
 
-	if (dev_handle >= 0) {
+	if (str_cmp(opts, "restore") == 0) {
 		if (tmpfs_restore(dev_handle))
 			ipc_answer_3(rid, EOK, root->index, root->size,
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/srv/vfs/vfs.h	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -255,4 +255,6 @@
 extern link_t plb_head;		/**< List of active PLB entries. */
 
+#define MAX_MNTOPTS_LEN		256
+
 /** Holding this rwlock prevents changes in file system namespace. */ 
 extern rwlock_t namespace_rwlock;
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision 6b6e423a2ae538739fa7ef8c7313e974cc4e9d97)
+++ uspace/srv/vfs/vfs_ops.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
@@ -61,4 +61,5 @@
 	char *fs_name;            /**< File system name */
 	char *mp;                 /**< Mount point */
+	char *opts;		  /**< Mount options. */
 	ipc_callid_t callid;      /**< Call ID waiting for the mount */
 	ipc_callid_t rid;         /**< Request ID */
@@ -81,11 +82,14 @@
 
 static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle,
-    fs_handle_t fs_handle, char *mp)
-{
-	/* Resolve the path to the mountpoint. */
+    fs_handle_t fs_handle, char *mp, char *opts)
+{
 	vfs_lookup_res_t mp_res;
 	vfs_node_t *mp_node = NULL;
-	int rc;
+	ipcarg_t rc;
 	int phone;
+	aid_t msg;
+	ipc_call_t answer;
+
+	/* Resolve the path to the mountpoint. */
 	futex_down(&rootfs_futex);
 	if (rootfs.fs_handle) {
@@ -128,7 +132,7 @@
 			vfs_lookup_res_t mr_res;
 			vfs_node_t *mr_node;
-			ipcarg_t rindex;
-			ipcarg_t rsize;
-			ipcarg_t rlnkcnt;
+			fs_index_t rindex;
+			size_t rsize;
+			unsigned rlnkcnt;
 			
 			/*
@@ -139,6 +143,17 @@
 			/* Tell the mountee that it is being mounted. */
 			phone = vfs_grab_phone(fs_handle);
-			rc = async_req_1_3(phone, VFS_MOUNTED,
-			    (ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt);
+			msg = async_send_1(phone, VFS_MOUNTED,
+			    (ipcarg_t) dev_handle, &answer);
+			/* send the mount options */
+			rc = ipc_data_write_start(phone, (void *)opts,
+			    str_size(opts));
+			if (rc != EOK) {
+				async_wait_for(msg, NULL);
+				vfs_release_phone(phone);
+				futex_up(&rootfs_futex);
+				ipc_answer_0(rid, rc);
+				return;
+			}
+			async_wait_for(msg, &rc);
 			vfs_release_phone(phone);
 			
@@ -148,10 +163,14 @@
 				return;
 			}
+
+			rindex = (fs_index_t) IPC_GET_ARG1(answer);
+			rsize = (size_t) IPC_GET_ARG2(answer);
+			rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
 			
 			mr_res.triplet.fs_handle = fs_handle;
 			mr_res.triplet.dev_handle = dev_handle;
-			mr_res.triplet.index = (fs_index_t) rindex;
-			mr_res.size = (size_t) rsize;
-			mr_res.lnkcnt = (unsigned) rlnkcnt;
+			mr_res.triplet.index = rindex;
+			mr_res.size = rsize;
+			mr_res.lnkcnt = rlnkcnt;
 			mr_res.type = VFS_NODE_DIRECTORY;
 			
@@ -184,9 +203,21 @@
 	
 	phone = vfs_grab_phone(mp_res.triplet.fs_handle);
-	rc = async_req_4_0(phone, VFS_MOUNT,
+	msg = async_send_4(phone, VFS_MOUNT,
 	    (ipcarg_t) mp_res.triplet.dev_handle,
 	    (ipcarg_t) mp_res.triplet.index,
 	    (ipcarg_t) fs_handle,
-	    (ipcarg_t) dev_handle);
+	    (ipcarg_t) dev_handle, &answer);
+	/* send the mount options */
+	rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));
+	if (rc != EOK) {
+		async_wait_for(msg, NULL);
+		vfs_release_phone(phone);
+		/* Mount failed, drop reference to mp_node. */
+		if (mp_node)
+			vfs_node_put(mp_node);
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	async_wait_for(msg, &rc);
 	vfs_release_phone(phone);
 	
@@ -217,8 +248,10 @@
 		
 		/* Do the mount */
-		vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp);
+		vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp,
+		    pr->opts);
 		
 		free(pr->fs_name);
 		free(pr->mp);
+		free(pr->opts);
 		list_remove(cur);
 		free(pr);
@@ -279,4 +312,39 @@
 	mp[size] = '\0';
 	
+	/* Now we expect to receive the mount options. */
+	if (!ipc_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 < 0 || 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 = ipc_data_write_finalize(callid, opts, size);
+	if (retval != EOK) {
+		ipc_answer_0(rid, retval);
+		free(mp);
+		free(opts);
+		return;
+	}
+	opts[size] = '\0';
+	
 	/*
 	 * Now, we expect the client to send us data with the name of the file
@@ -287,4 +355,5 @@
 		ipc_answer_0(rid, EINVAL);
 		free(mp);
+		free(opts);
 		return;
 	}
@@ -298,4 +367,5 @@
 		ipc_answer_0(rid, EINVAL);
 		free(mp);
+		free(opts);
 		return;
 	}
@@ -309,4 +379,5 @@
 		ipc_answer_0(rid, ENOMEM);
 		free(mp);
+		free(opts);
 		return;
 	}
@@ -317,4 +388,5 @@
 		ipc_answer_0(rid, retval);
 		free(mp);
+		free(opts);
 		free(fs_name);
 		return;
@@ -332,4 +404,5 @@
 		ipc_answer_0(rid, ENOTSUP);
 		free(mp);
+		free(opts);
 		free(fs_name);
 		return;
@@ -352,4 +425,5 @@
 				free(mp);
 				free(fs_name);
+				free(opts);
 				return;
 			}
@@ -357,4 +431,5 @@
 			pr->fs_name = fs_name;
 			pr->mp = mp;
+			pr->opts = opts;
 			pr->callid = callid;
 			pr->rid = rid;
@@ -369,4 +444,5 @@
 		free(mp);
 		free(fs_name);
+		free(opts);
 		return;
 	}
@@ -376,7 +452,8 @@
 	
 	/* Do the mount */
-	vfs_mount_internal(rid, dev_handle, fs_handle, mp);
+	vfs_mount_internal(rid, dev_handle, fs_handle, mp, opts);
 	free(mp);
 	free(fs_name);
+	free(opts);
 }
 
