Index: uspace/srv/fs/ext4fs/ext4fs_ops.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision d3a9ae741fa4b45ceb2552332ad3519381c720f1)
+++ uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 00a8f1b5bbb2bdb8f3cac63fc23b4c833ae23f12)
@@ -37,8 +37,34 @@
 
 #include <errno.h>
+#include <fibril_synch.h>
+#include <libext4.h>
 #include <libfs.h>
+#include <malloc.h>
 #include <ipc/loc.h>
 #include "ext4fs.h"
 #include "../../vfs/vfs.h"
+
+#define EXT4FS_NODE(node)	((node) ? (ext4fs_node_t *) (node)->data : NULL)
+
+typedef struct ext4fs_instance {
+	link_t link;
+	service_id_t service_id;
+	ext4_filesystem_t *filesystem;
+	unsigned int open_nodes_count;
+} ext4fs_instance_t;
+
+typedef struct ext4fs_node {
+	ext4fs_instance_t *instance;
+	ext4_inode_ref_t *inode_ref;
+	fs_node_t *fs_node;
+	link_t link;
+	unsigned int references;
+} ext4fs_node_t;
+
+/*
+ * Forward declarations of auxiliary functions
+ */
+static int ext4fs_instance_get(service_id_t, ext4fs_instance_t **);
+static int ext4fs_node_get_core(fs_node_t **, ext4fs_instance_t *, fs_index_t);
 
 
@@ -63,4 +89,12 @@
 static service_id_t ext4fs_service_get(fs_node_t *node);
 
+/*
+ * Static variables
+ */
+static LIST_INITIALIZE(instance_list);
+static FIBRIL_MUTEX_INITIALIZE(instance_list_mutex);
+static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
+
+
 /**
  *	TODO comment
@@ -83,4 +117,29 @@
  */
 
+int ext4fs_instance_get(service_id_t service_id, ext4fs_instance_t **inst)
+{
+	ext4fs_instance_t *tmp;
+
+	fibril_mutex_lock(&instance_list_mutex);
+
+	if (list_empty(&instance_list)) {
+		fibril_mutex_unlock(&instance_list_mutex);
+		return EINVAL;
+	}
+
+	list_foreach(instance_list, link) {
+		tmp = list_get_instance(link, ext4fs_instance_t, link);
+
+		if (tmp->service_id == service_id) {
+			*inst = tmp;
+			fibril_mutex_unlock(&instance_list_mutex);
+			return EOK;
+		}
+	}
+
+	fibril_mutex_unlock(&instance_list_mutex);
+	return EINVAL;
+}
+
 int ext4fs_root_get(fs_node_t **rfn, service_id_t service_id)
 {
@@ -99,4 +158,11 @@
 	// TODO
 	return 0;
+}
+
+int ext4fs_node_get_core(fs_node_t **rfn, ext4fs_instance_t *inst,
+		fs_index_t index)
+{
+	// TODO
+	return EOK;
 }
 
@@ -210,5 +276,77 @@
    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
 {
-	// TODO
+
+	int rc;
+	ext4_filesystem_t *fs;
+	ext4fs_instance_t *inst;
+	bool read_only;
+
+	/* Allocate libext4 filesystem structure */
+	fs = (ext4_filesystem_t *) malloc(sizeof(ext4_filesystem_t));
+	if (fs == NULL) {
+		return ENOMEM;
+	}
+
+	/* Allocate instance structure */
+	inst = (ext4fs_instance_t *) malloc(sizeof(ext4fs_instance_t));
+	if (inst == NULL) {
+		free(fs);
+		return ENOMEM;
+	}
+
+	/* Initialize the filesystem  */
+	rc = ext4_filesystem_init(fs, service_id);
+	if (rc != EOK) {
+		free(fs);
+		free(inst);
+		return rc;
+	}
+
+	/* Do some sanity checking */
+	rc = ext4_filesystem_check_sanity(fs);
+	if (rc != EOK) {
+		ext4_filesystem_fini(fs);
+		free(fs);
+		free(inst);
+		return rc;
+	}
+
+	/* Check flags */
+	rc = ext4_filesystem_check_flags(fs, &read_only);
+	if (rc != EOK) {
+		ext4_filesystem_fini(fs);
+		free(fs);
+		free(inst);
+		return rc;
+	}
+
+	/* Initialize instance */
+	link_initialize(&inst->link);
+	inst->service_id = service_id;
+	inst->filesystem = fs;
+	inst->open_nodes_count = 0;
+
+	/* Read root node */
+	fs_node_t *root_node;
+	rc = ext4fs_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
+	if (rc != EOK) {
+		ext4_filesystem_fini(fs);
+		free(fs);
+		free(inst);
+		return rc;
+	}
+	ext4fs_node_t *enode = EXT4FS_NODE(root_node);
+
+	/* Add instance to the list */
+	fibril_mutex_lock(&instance_list_mutex);
+	list_append(&inst->link, &instance_list);
+	fibril_mutex_unlock(&instance_list_mutex);
+
+	*index = EXT4_INODE_ROOT_INDEX;
+	*size = 0;
+	*lnkcnt = ext4_inode_get_usage_count(enode->inode_ref->inode);
+
+	ext4fs_node_put(root_node);
+
 	return EOK;
 }
@@ -216,5 +354,30 @@
 static int ext4fs_unmounted(service_id_t service_id)
 {
-	// TODO
+
+	int rc;
+	ext4fs_instance_t *inst;
+
+	rc = ext4fs_instance_get(service_id, &inst);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	fibril_mutex_lock(&open_nodes_lock);
+
+	if (inst->open_nodes_count != 0) {
+		fibril_mutex_unlock(&open_nodes_lock);
+		return EBUSY;
+	}
+
+	/* Remove the instance from the list */
+	fibril_mutex_lock(&instance_list_mutex);
+	list_remove(&inst->link);
+	fibril_mutex_unlock(&instance_list_mutex);
+
+	fibril_mutex_unlock(&open_nodes_lock);
+
+	ext4_filesystem_fini(inst->filesystem);
+
 	return EOK;
 }
