Index: uspace/lib/ext4/include/ext4/filesystem.h
===================================================================
--- uspace/lib/ext4/include/ext4/filesystem.h	(revision be39fc6933dcee0f4da8cad1a1eb341979fbb8ce)
+++ uspace/lib/ext4/include/ext4/filesystem.h	(revision de5b70813566c7291db107dbb4525d91b6246d02)
@@ -39,7 +39,7 @@
 #include "ext4/types.h"
 
-extern int ext4_filesystem_init(ext4_filesystem_t *, ext4_instance_t *,
-    service_id_t, enum cache_mode, aoff64_t *);
-extern int ext4_filesystem_fini(ext4_filesystem_t *);
+extern int ext4_filesystem_open(ext4_instance_t *, service_id_t,
+    enum cache_mode, aoff64_t *, ext4_filesystem_t **);
+extern int ext4_filesystem_close(ext4_filesystem_t *);
 extern uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *,
     uint32_t);
Index: uspace/lib/ext4/src/filesystem.c
===================================================================
--- uspace/lib/ext4/src/filesystem.c	(revision be39fc6933dcee0f4da8cad1a1eb341979fbb8ce)
+++ uspace/lib/ext4/src/filesystem.c	(revision de5b70813566c7291db107dbb4525d91b6246d02)
@@ -56,19 +56,17 @@
 static int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
 
-/** Initialize filesystem and read all needed data.
+/** Initialize filesystem for opening.
+ *
+ * But do not mark mounted just yet.
  *
  * @param fs         Filesystem instance to be initialized
  * @param service_id Identifier if device with the filesystem
  * @param cmode      Cache mode
- * @param read_only  Place to store read only flag
- * @param index      Output value - index of root node
- * @param size       Output value - size of root node
- * @param lnkcnt     Output value - link count of root node
  *
  * @return Error code
  *
  */
-int ext4_filesystem_init(ext4_filesystem_t *fs, ext4_instance_t *inst,
-    service_id_t service_id, enum cache_mode cmode, aoff64_t *size)
+static int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id,
+    enum cache_mode cmode)
 {
 	int rc;
@@ -122,5 +120,5 @@
 		goto err_2;
 	}
-	
+
 	rc = ext4_superblock_check_sanity(fs->superblock);
 	if (rc != EOK)
@@ -133,27 +131,5 @@
 		goto err_2;
 
-	/* Read root node */
-	fs_node_t *root_node;
-	rc = ext4_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
-	if (rc != EOK)
-		goto err_2;
-
-	/* Mark system as mounted */
-	ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
-	rc = ext4_superblock_write_direct(fs->device, fs->superblock);
-	if (rc != EOK)
-		goto err_3;
-
-	uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
-	ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
-
-	ext4_node_t *enode = EXT4_NODE(root_node);
-	
-	*size = ext4_inode_get_size(fs->superblock, enode->inode_ref->inode);
-
-	ext4_node_put(root_node);
 	return EOK;
-err_3:
-	ext4_node_put(root_node);
 err_2:
 	block_cache_fini(fs->device);
@@ -166,25 +142,101 @@
 }
 
-/** Destroy filesystem instance (used by unmount operation).
+/** Finalize filesystem.
+ *
+ * @param fs Filesystem to be finalized
+ *
+ */
+static void ext4_filesystem_fini(ext4_filesystem_t *fs)
+{
+	/* Release memory space for superblock */
+	free(fs->superblock);
+
+	/* Finish work with block library */
+	block_cache_fini(fs->device);
+	block_fini(fs->device);
+}
+
+/** Open filesystem and read all needed data.
+ *
+ * @param fs         Filesystem to be initialized
+ * @param inst       Instance
+ * @param service_id Identifier if device with the filesystem
+ * @param cmode      Cache mode
+ * @param size       Output value - size of root node
+ *
+ * @return Error code
+ *
+ */
+int ext4_filesystem_open(ext4_instance_t *inst, service_id_t service_id,
+    enum cache_mode cmode, aoff64_t *size, ext4_filesystem_t **rfs)
+{
+	ext4_filesystem_t *fs = NULL;
+	fs_node_t *root_node = NULL;
+	int rc;
+
+	fs = calloc(1, sizeof(ext4_filesystem_t));
+	if (fs == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	inst->filesystem = fs;
+
+	/* Initialize the file system for opening */
+	rc = ext4_filesystem_init(fs, service_id, cmode);
+	if (rc != EOK)
+		goto error;
+
+	/* Read root node */
+	rc = ext4_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
+	if (rc != EOK)
+		goto error;
+
+	/* Mark system as mounted */
+	ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
+	rc = ext4_superblock_write_direct(fs->device, fs->superblock);
+	if (rc != EOK)
+		goto error;
+
+	uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
+	ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
+
+	ext4_node_t *enode = EXT4_NODE(root_node);
+
+	*size = ext4_inode_get_size(fs->superblock, enode->inode_ref->inode);
+
+	ext4_node_put(root_node);
+	*rfs = fs;
+	return EOK;
+error:
+	if (root_node != NULL)
+		ext4_node_put(root_node);
+
+	if (fs != NULL) {
+		ext4_filesystem_fini(fs);
+		free(fs);
+	}
+
+	return rc;
+}
+
+/** Close filesystem.
  *
  * @param fs Filesystem to be destroyed
  *
- * @return Error code
- *
- */
-int ext4_filesystem_fini(ext4_filesystem_t *fs)
+ * @return EOK or negative error code. On error the state of the file
+ *         system is unchanged.
+ *
+ */
+int ext4_filesystem_close(ext4_filesystem_t *fs)
 {
 	/* Write the superblock to the device */
 	ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
 	int rc = ext4_superblock_write_direct(fs->device, fs->superblock);
-	
-	/* Release memory space for superblock */
-	free(fs->superblock);
-
-	/* Finish work with block library */
-	block_cache_fini(fs->device);
-	block_fini(fs->device);
-	
-	return rc;
+	if (rc != EOK)
+		return rc;
+
+	ext4_filesystem_fini(fs);
+	return EOK;
 }
 
Index: uspace/lib/ext4/src/ops.c
===================================================================
--- uspace/lib/ext4/src/ops.c	(revision be39fc6933dcee0f4da8cad1a1eb341979fbb8ce)
+++ uspace/lib/ext4/src/ops.c	(revision de5b70813566c7291db107dbb4525d91b6246d02)
@@ -928,17 +928,11 @@
     fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
 {
-	/* Allocate libext4 filesystem structure */
-	ext4_filesystem_t *fs = (ext4_filesystem_t *)
-	    malloc(sizeof(ext4_filesystem_t));
-	if (fs == NULL)
-		return ENOMEM;
+	ext4_filesystem_t *fs;
 	
 	/* Allocate instance structure */
 	ext4_instance_t *inst = (ext4_instance_t *)
 	    malloc(sizeof(ext4_instance_t));
-	if (inst == NULL) {
-		free(fs);
+	if (inst == NULL)
 		return ENOMEM;
-	}
 	
 	enum cache_mode cmode;
@@ -951,12 +945,10 @@
 	link_initialize(&inst->link);
 	inst->service_id = service_id;
-	inst->filesystem = fs;
 	inst->open_nodes_count = 0;
 	
 	/* Initialize the filesystem */
 	aoff64_t rnsize;
-	int rc = ext4_filesystem_init(fs, inst, service_id, cmode, &rnsize);
-	if (rc != EOK) {
-		free(fs);
+	int rc = ext4_filesystem_open(inst, service_id, cmode, &rnsize, &fs);
+	if (rc != EOK) {
 		free(inst);
 		return rc;
@@ -1005,5 +997,13 @@
 	fibril_mutex_unlock(&open_nodes_lock);
 	
-	return ext4_filesystem_fini(inst->filesystem);
+	rc = ext4_filesystem_close(inst->filesystem);
+	if (rc != EOK) {
+		fibril_mutex_lock(&instance_list_mutex);
+		list_append(&inst->link, &instance_list);
+		fibril_mutex_unlock(&instance_list_mutex);
+	}
+
+	free(inst);
+	return EOK;
 }
 
