Index: uspace/srv/fs/tmpfs/Makefile
===================================================================
--- uspace/srv/fs/tmpfs/Makefile	(revision 7f880ee806bd0005673c0a4b8e4e98808da44467)
+++ uspace/srv/fs/tmpfs/Makefile	(revision 40257f573530dfd8a6fe333cbdf01104c782effa)
@@ -45,5 +45,6 @@
 SOURCES = \
 	tmpfs.c \
-	tmpfs_ops.c
+	tmpfs_ops.c \
+	tmpfs_dump.c
 
 OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
Index: uspace/srv/fs/tmpfs/tmpfs.h
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.h	(revision 7f880ee806bd0005673c0a4b8e4e98808da44467)
+++ uspace/srv/fs/tmpfs/tmpfs.h	(revision 40257f573530dfd8a6fe333cbdf01104c782effa)
@@ -61,4 +61,6 @@
 extern fs_reg_t tmpfs_reg;
 
+extern libfs_ops_t tmpfs_libfs_ops;
+
 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
@@ -68,4 +70,6 @@
 extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
 
+extern bool tmpfs_restore(dev_handle_t);
+
 #endif
 
Index: uspace/srv/fs/tmpfs/tmpfs_dump.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_dump.c	(revision 40257f573530dfd8a6fe333cbdf01104c782effa)
+++ uspace/srv/fs/tmpfs/tmpfs_dump.c	(revision 40257f573530dfd8a6fe333cbdf01104c782effa)
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2008 Jakub Jermar 
+ * Copyright (c) 2008 Martin Decky 
+ * 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	tmpfs_dump.c
+ * @brief	Support for loading TMPFS file system dump.
+ */
+
+#include "tmpfs.h"
+#include "../../vfs/vfs.h"
+#include <ipc/ipc.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <as.h>
+#include <libfs.h>
+#include <ipc/services.h>
+#include <ipc/devmap.h>
+#include <sys/mman.h>
+#include <byteorder.h>
+
+#define BLOCK_SIZE			1024	// FIXME
+#define RD_BASE				1024	// FIXME
+#define	RD_READ_BLOCK	(RD_BASE + 1)
+
+struct rdentry {
+	uint8_t type;
+	uint32_t len;
+} __attribute__((packed));
+
+static bool 
+tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen,
+    size_t *pos, void *dst, size_t size)
+{
+	size_t offset = 0;
+	size_t left = size;
+	
+	while (left > 0) {
+		size_t rd;
+		
+		if (*bufpos + left < *buflen)
+			rd = left;
+		else
+			rd = *buflen - *bufpos;
+		
+		if (rd > 0) {
+			memcpy(dst + offset, buffer + *bufpos, rd);
+			offset += rd;
+			*bufpos += rd;
+			*pos += rd;
+			left -= rd;
+		}
+		
+		if (*bufpos == *buflen) {
+			ipcarg_t retval;
+			int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK,
+			    *pos / BLOCK_SIZE, BLOCK_SIZE,
+			    &retval);
+			if ((rc != EOK) || (retval != EOK))
+				return false;
+			
+			*bufpos = 0;
+			*buflen = BLOCK_SIZE;
+		}
+	}
+	
+	return true;
+}
+
+static bool
+tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen,
+    size_t *pos, tmpfs_dentry_t *parent)
+{
+	struct rdentry entry;
+	libfs_ops_t *ops = &tmpfs_libfs_ops;
+	
+	do {
+		char *fname;
+		tmpfs_dentry_t *node;
+		uint32_t size;
+		
+		if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry,
+		    sizeof(entry)))
+			return false;
+		
+		entry.len = uint32_t_le2host(entry.len);
+		
+		switch (entry.type) {
+		case 0:
+			break;
+		case 1:
+			fname = malloc(entry.len + 1);
+			if (fname == NULL)
+				return false;
+			
+			node = (tmpfs_dentry_t *) ops->create(L_FILE);
+			if (node == NULL) {
+				free(fname);
+				return false;
+			}
+			
+			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
+			    fname, entry.len)) {
+				ops->destroy((void *) node);
+				free(fname);
+				return false;
+			}
+			fname[entry.len] = 0;
+			
+			if (!ops->link((void *) parent, (void *) node, fname)) {
+				ops->destroy((void *) node);
+				free(fname);
+				return false;
+			}
+			free(fname);
+			
+			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
+			    &size, sizeof(size)))
+				return false;
+			
+			size = uint32_t_le2host(size);
+			
+			node->data = malloc(size);
+			if (node->data == NULL)
+				return false;
+			
+			node->size = size;
+			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
+			    node->data, size))
+				return false;
+			
+			break;
+		case 2:
+			fname = malloc(entry.len + 1);
+			if (fname == NULL)
+				return false;
+			
+			node = (tmpfs_dentry_t *) ops->create(L_DIRECTORY);
+			if (node == NULL) {
+				free(fname);
+				return false;
+			}
+			
+			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos,
+			    fname, entry.len)) {
+				ops->destroy((void *) node);
+				free(fname);
+				return false;
+			}
+			fname[entry.len] = 0;
+			
+			if (!ops->link((void *) parent, (void *) node, fname)) {
+				ops->destroy((void *) node);
+				free(fname);
+				return false;
+			}
+			free(fname);
+			
+			if (!tmpfs_restore_recursion(phone, block, bufpos,
+			    buflen, pos, node))
+				return false;
+			
+			break;
+		default:
+			return false;
+		}
+	} while (entry.type != 0);
+	
+	return true;
+}
+
+bool tmpfs_restore(dev_handle_t dev)
+{
+	libfs_ops_t *ops = &tmpfs_libfs_ops;
+
+	void *block = mmap(NULL, BLOCK_SIZE,
+	    PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+	
+	if (block == NULL)
+		return false;
+	
+	int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
+	    DEVMAP_CONNECT_TO_DEVICE, dev);
+
+	if (phone < 0) {
+		munmap(block, BLOCK_SIZE);
+		return false;
+	}
+	
+	if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) !=
+	    EOK)
+		goto error;
+	
+	size_t bufpos = 0;
+	size_t buflen = 0;
+	size_t pos = 0;
+	
+	char tag[6];
+	if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5))
+		goto error;
+	
+	tag[5] = 0;
+	if (strcmp(tag, "TMPFS") != 0)
+		goto error;
+	
+	if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos,
+	    ops->root_get(dev)))
+		goto error;
+		
+	ipc_hangup(phone);
+	munmap(block, BLOCK_SIZE);
+	return true;
+	
+error:
+	ipc_hangup(phone);
+	munmap(block, BLOCK_SIZE);
+	return false;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 7f880ee806bd0005673c0a4b8e4e98808da44467)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 40257f573530dfd8a6fe333cbdf01104c782effa)
@@ -51,8 +51,4 @@
 #include <as.h>
 #include <libfs.h>
-#include <ipc/services.h>
-#include <ipc/devmap.h>
-#include <sys/mman.h>
-#include <byteorder.h>
 
 #define min(a, b)		((a) < (b) ? (a) : (b))
@@ -62,8 +58,4 @@
 
 #define NAMES_BUCKETS		4
-
-#define BLOCK_SIZE			1024	// FIXME
-#define RD_BASE				1024	// FIXME
-#define	RD_READ_BLOCK	(RD_BASE + 1)
 
 /*
@@ -149,9 +141,4 @@
 hash_table_t dentries;
 
-struct rdentry {
-	uint8_t type;
-	uint32_t len;
-} __attribute__((packed));
-
 /* Implementation of hash table interface for the dentries hash table. */
 static hash_index_t dentries_hash(unsigned long *key)
@@ -249,177 +236,4 @@
 	root->lnkcnt = 1;
 	return true;
-}
-
-static bool tmpfs_blockread(int phone, void *buffer, size_t *bufpos, size_t *buflen, size_t *pos, void *dst, size_t size)
-{
-	size_t offset = 0;
-	size_t left = size;
-	
-	while (left > 0) {
-		size_t rd;
-		
-		if (*bufpos + left < *buflen)
-			rd = left;
-		else
-			rd = *buflen - *bufpos;
-		
-		if (rd > 0) {
-			memcpy(dst + offset, buffer + *bufpos, rd);
-			offset += rd;
-			*bufpos += rd;
-			*pos += rd;
-			left -= rd;
-		}
-		
-		if (*bufpos == *buflen) {
-			ipcarg_t retval;
-			int rc = ipc_call_sync_2_1(phone, RD_READ_BLOCK,
-			    *pos / BLOCK_SIZE, BLOCK_SIZE,
-			    &retval);
-			if ((rc != EOK) || (retval != EOK))
-				return false;
-			
-			*bufpos = 0;
-			*buflen = BLOCK_SIZE;
-		}
-	}
-	
-	return true;
-}
-
-static bool tmpfs_restore_recursion(int phone, void *block, size_t *bufpos, size_t *buflen, size_t *pos, tmpfs_dentry_t *parent)
-{
-	struct rdentry entry;
-	
-	do {
-		char *fname;
-		tmpfs_dentry_t *node;
-		uint32_t size;
-		
-		if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &entry, sizeof(entry)))
-			return false;
-		
-		entry.len = uint32_t_le2host(entry.len);
-		
-		switch (entry.type) {
-		case 0:
-			break;
-		case 1:
-			fname = malloc(entry.len + 1);
-			if (fname == NULL)
-				return false;
-			
-			node = (tmpfs_dentry_t *) tmpfs_create_node(L_FILE);
-			if (node == NULL) {
-				free(fname);
-				return false;
-			}
-			
-			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) {
-				tmpfs_destroy_node((void *) node);
-				free(fname);
-				return false;
-			}
-			fname[entry.len] = 0;
-			
-			if (!tmpfs_link_node((void *) parent, (void *) node, fname)) {
-				tmpfs_destroy_node((void *) node);
-				free(fname);
-				return false;
-			}
-			free(fname);
-			
-			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, &size, sizeof(size)))
-				return false;
-			
-			size = uint32_t_le2host(size);
-			
-			node->data = malloc(size);
-			if (node->data == NULL)
-				return false;
-			
-			node->size = size;
-			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, node->data, size))
-				return false;
-			
-			break;
-		case 2:
-			fname = malloc(entry.len + 1);
-			if (fname == NULL)
-				return false;
-			
-			node = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
-			if (node == NULL) {
-				free(fname);
-				return false;
-			}
-			
-			if (!tmpfs_blockread(phone, block, bufpos, buflen, pos, fname, entry.len)) {
-				tmpfs_destroy_node((void *) node);
-				free(fname);
-				return false;
-			}
-			fname[entry.len] = 0;
-			
-			if (!tmpfs_link_node((void *) parent, (void *) node, fname)) {
-				tmpfs_destroy_node((void *) node);
-				free(fname);
-				return false;
-			}
-			free(fname);
-			
-			if (!tmpfs_restore_recursion(phone, block, bufpos, buflen, pos, node))
-				return false;
-			
-			break;
-		default:
-			return false;
-		}
-	} while (entry.type != 0);
-	
-	return true;
-}
-
-static bool tmpfs_restore(dev_handle_t dev)
-{
-	void *block = mmap(NULL, BLOCK_SIZE,
-	    PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
-	
-	if (block == NULL)
-		return false;
-	
-	int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, dev);
-
-	if (phone < 0) {
-		munmap(block, BLOCK_SIZE);
-		return false;
-	}
-	
-	if (ipc_share_out_start(phone, block, AS_AREA_READ | AS_AREA_WRITE) != EOK)
-		goto error;
-	
-	size_t bufpos = 0;
-	size_t buflen = 0;
-	size_t pos = 0;
-	
-	char tag[6];
-	if (!tmpfs_blockread(phone, block, &bufpos, &buflen, &pos, tag, 5))
-		goto error;
-	
-	tag[5] = 0;
-	if (strcmp(tag, "TMPFS") != 0)
-		goto error;
-	
-	if (!tmpfs_restore_recursion(phone, block, &bufpos, &buflen, &pos, root))
-		goto error;
-		
-	ipc_hangup(phone);
-	munmap(block, BLOCK_SIZE);
-	return true;
-	
-error:
-	ipc_hangup(phone);
-	munmap(block, BLOCK_SIZE);
-	return false;
 }
 
