Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/Makefile.common	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -115,4 +115,5 @@
 
 LIBEXT2_PREFIX = $(LIB_PREFIX)/ext2
+LIBEXT4_PREFIX = $(LIB_PREFIX)/ext4
 
 LIBUSB_PREFIX = $(LIB_PREFIX)/usb
Index: uspace/lib/ext4/Makefile
===================================================================
--- uspace/lib/ext4/Makefile	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/Makefile	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -33,8 +33,10 @@
 
 SOURCES = \
-	libext4_superblock.c \
 	libext4_block_group.c \
+	libext4_directory.c \
+	libext4_filesystem.c \
 	libext4_inode.c \
-	libext4_directory.c
+	libext4_superblock.c
+	
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/ext4/libext4.h
===================================================================
--- uspace/lib/ext4/libext4.h	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4.h	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -36,4 +36,5 @@
 #include "libext4_block_group.h"
 #include "libext4_directory.h"
+#include "libext4_filesystem.h"
 #include "libext4_inode.h"
 #include "libext4_superblock.h"
Index: uspace/lib/ext4/libext4_block_group.c
===================================================================
--- uspace/lib/ext4/libext4_block_group.c	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4_block_group.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -36,4 +36,5 @@
  */
 
+#include "libext4_block_group.h"
 
 
Index: uspace/lib/ext4/libext4_block_group.h
===================================================================
--- uspace/lib/ext4/libext4_block_group.h	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4_block_group.h	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -34,4 +34,29 @@
 #define LIBEXT4_LIBEXT4_BLOCK_GROUP_H_
 
+#include <sys/types.h>
+
+/*
+ * Structure of a blocks group descriptor
+ */
+typedef struct ext4_block_group {
+	uint32_t bg_block_bitmap_lo; // Blocks bitmap block
+	uint32_t bg_inode_bitmap_lo; // Inodes bitmap block
+	uint32_t bg_inode_table_lo; // Inodes table block
+	uint16_t bg_free_blocks_count_lo; // Free blocks count
+	uint16_t bg_free_inodes_count_lo; // Free inodes count
+	uint16_t bg_used_dirs_count_lo; // Directories count
+	uint16_t bg_flags; // EXT4_BG_flags (INODE_UNINIT, etc)
+	uint32_t bg_reserved[2]; // Likely block/inode bitmap checksum
+	uint16_t bg_itable_unused_lo; // Unused inodes count
+	uint16_t bg_checksum; // crc16(sb_uuid+group+desc)
+	uint32_t bg_block_bitmap_hi; // Blocks bitmap block MSB
+	uint32_t bg_inode_bitmap_hi; // Inodes bitmap block MSB
+	uint32_t bg_inode_table_hi; // Inodes table block MSB
+	uint16_t bg_free_blocks_count_hi; // Free blocks count MSB
+	uint16_t bg_free_inodes_count_hi; // Free inodes count MSB
+	uint16_t bg_used_dirs_count_hi; // Directories count MSB
+	uint16_t bg_itable_unused_hi;  // Unused inodes count MSB
+	uint32_t bg_reserved2[3]; // Padding
+} ext4_group_desc_t;
 
 #endif
Index: uspace/lib/ext4/libext4_directory.c
===================================================================
--- uspace/lib/ext4/libext4_directory.c	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4_directory.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -36,4 +36,5 @@
  */
 
+#include "libext4_directory.h"
 
 
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011 Frantisek Princ
+ * 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 libext4
+ * @{
+ */ 
+
+/**
+ * @file	libext4_filesystem.c
+ * @brief	TODO
+ */
+
+#include <errno.h>
+#include "libext4_filesystem.h"
+
+int ext4_filesystem_init(ext4_filesystem_t *fs, service_id_t service_id)
+{
+	// TODO
+	return EOK;
+}
+
+int ext4_filesystem_check_sanity(ext4_filesystem_t *fs)
+{
+	// TODO
+	return EOK;
+}
+
+int ext4_filesystem_check_flags(ext4_filesystem_t *fs, bool *o_read_only)
+{
+	// TODO
+	return EOK;
+}
+
+void ext4_filesystem_fini(ext4_filesystem_t *fs)
+{
+	// TODO
+}
+
+
+/**
+ * @}
+ */ 
Index: uspace/lib/ext4/libext4_filesystem.h
===================================================================
--- uspace/lib/ext4/libext4_filesystem.h	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
+++ uspace/lib/ext4/libext4_filesystem.h	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 Frantisek Princ
+ * 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 libext4
+ * @{
+ */ 
+
+#ifndef LIBEXT4_LIBEXT4_FILESYSTEM_H_
+#define LIBEXT4_LIBEXT4_FILESYSTEM_H_
+
+#include <libblock.h>
+#include "libext4_superblock.h"
+
+typedef struct ext4_filesystem {
+	service_id_t device;
+	ext4_superblock_t *	superblock;
+} ext4_filesystem_t;
+
+extern int ext4_filesystem_init(ext4_filesystem_t *, service_id_t);
+extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs);
+extern int ext4_filesystem_check_flags(ext4_filesystem_t *, bool *);
+extern void ext4_filesystem_fini(ext4_filesystem_t *fs);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/ext4/libext4_inode.c
===================================================================
--- uspace/lib/ext4/libext4_inode.c	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4_inode.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -36,5 +36,13 @@
  */
 
-#include "libext4.h"
+#include "libext4_inode.h"
+
+// TODO check return type
+uint16_t ext4_inode_get_usage_count(ext4_inode_t *inode)
+{
+	// TODO
+	return 0;
+}
+
 
 /**
Index: uspace/lib/ext4/libext4_inode.h
===================================================================
--- uspace/lib/ext4/libext4_inode.h	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4_inode.h	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -34,4 +34,5 @@
 #define LIBEXT4_LIBEXT4_INODE_H_
 
+#include <libblock.h>
 #include <sys/types.h>
 
@@ -112,4 +113,14 @@
 
 
+// TODO check value
+#define EXT4_INODE_ROOT_INDEX	2
+
+typedef struct ext4_inode_ref {
+	block_t *block; // Reference to a block containing this inode
+	ext4_inode_t *inode;
+	uint32_t index; // Index number of this inode
+} ext4_inode_ref_t;
+
+extern uint16_t ext4_inode_get_usage_count(ext4_inode_t *);
 
 #endif
Index: uspace/lib/ext4/libext4_superblock.c
===================================================================
--- uspace/lib/ext4/libext4_superblock.c	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/lib/ext4/libext4_superblock.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -36,5 +36,5 @@
  */
 
-#include "libext4.h"
+#include "libext4_superblock.h"
 
 
Index: uspace/srv/fs/ext4fs/Makefile
===================================================================
--- uspace/srv/fs/ext4fs/Makefile	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/srv/fs/ext4fs/Makefile	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -28,6 +28,6 @@
 
 USPACE_PREFIX = ../../..
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a
-EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX)
+LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a $(LIBEXT4_PREFIX)/libext4.a
+EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX) -I$(LIBEXT4_PREFIX)
 BINARY = ext4fs
 
Index: uspace/srv/fs/ext4fs/ext4fs_ops.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 9875711e14b473f7c2f2a7d8717c92db3f548472)
+++ uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision 6c501f8ff98956b3a251fb0b81b404ae0ecf44a1)
@@ -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;
 }
