shithub: lwext4

Download patch

ref: d868262d36283441a727e1022414ac706abddb59
parent: 7b3739e7e42e753f9e5b3820b876ff1430243a10
author: gkostka <kostka.grzegorz@gmail.com>
date: Sun Oct 13 13:36:52 EDT 2013

Update directory tree.

diff: cannot open b/blockdev/filedev//null: file does not exist: 'b/blockdev/filedev//null' diff: cannot open b/blockdev//null: file does not exist: 'b/blockdev//null' diff: cannot open b/demos/generic//null: file does not exist: 'b/demos/generic//null' diff: cannot open b/demos//null: file does not exist: 'b/demos//null' diff: cannot open b/lwext4//null: file does not exist: 'b/lwext4//null' diff: cannot open a/src/blockdev/filedev//null: file does not exist: 'a/src/blockdev/filedev//null' diff: cannot open a/src/blockdev//null: file does not exist: 'a/src/blockdev//null' diff: cannot open a/src/demos/generic//null: file does not exist: 'a/src/demos/generic//null' diff: cannot open a/src/demos//null: file does not exist: 'a/src/demos//null' diff: cannot open a/src/lwext4//null: file does not exist: 'a/src/lwext4//null' diff: cannot open a/src/toolchain//null: file does not exist: 'a/src/toolchain//null' diff: cannot open a/src//null: file does not exist: 'a/src//null' diff: cannot open b/toolchain//null: file does not exist: 'b/toolchain//null'
--- /dev/null
+++ b/CMakeLists.txt
@@ -1,0 +1,46 @@
+project(lwext4 C)
+cmake_minimum_required(VERSION 2.8)
+
+
+#LIBRARY
+include_directories(. lwext4)
+aux_source_directory(lwext4 LWEXT4_SRC)
+add_library(lwext4  ${LWEXT4_SRC})
+
+
+#EXECUTABLE
+
+if(CMAKE_SYSTEM_PROCESSOR STREQUAL  cortex-m3)
+#Library size print
+add_custom_target(size ALL DEPENDS lwext4 COMMAND ${SIZE} -B liblwext4.a)
+
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL  cortex-m4)
+#Library size print
+add_custom_target(size ALL DEPENDS lwext4 COMMAND ${SIZE} -B liblwext4.a)
+
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL  bf518)
+#Library size print
+add_custom_target(size ALL DEPENDS lwext4 COMMAND ${SIZE} -B liblwext4.a)
+
+else()
+#Generic example target
+include_directories(blockdev/filedev)
+aux_source_directory(blockdev/filedev FILEDEV_SRC)
+aux_source_directory(demos/generic GENERIC_SRC)
+add_executable(fileimage_demo ${GENERIC_SRC} ${FILEDEV_SRC})
+target_link_libraries(fileimage_demo lwext4)
+add_custom_target(size ALL DEPENDS lwext4 COMMAND size -B liblwext4.a)
+endif()
+
+#DISTRIBUTION
+set(CPACK_PACKAGE_VERSION_MAJOR "0")
+set(CPACK_PACKAGE_VERSION_MINOR "1")
+set(CPACK_PACKAGE_VERSION_PATCH "1")
+set(CPACK_SOURCE_GENERATOR "TBZ2")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME
+  "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+set(CPACK_SOURCE_IGNORE_FILES
+"/build")
+include(CPack)
+
+add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
--- /dev/null
+++ b/Makefile
@@ -1,0 +1,36 @@
+
+all: generic bf518 cortex-m3 cortex-m4 generic
+
+bf518:
+	rm -R -f build_bf518
+	mkdir build_bf518
+	cd build_bf518 && cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchain/bf518.cmake ..
+	cd build_bf518 && make
+
+cortex-m3:
+	rm -R -f build_cortex-m3
+	mkdir build_cortex-m3
+	cd build_cortex-m3 && cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchain/cortex-m3.cmake ..
+	cd build_cortex-m3 && make
+
+cortex-m4:
+	rm -R -f build_cortex-m4
+	mkdir build_cortex-m4
+	cd build_cortex-m4 && cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchain/cortex-m4.cmake ..
+	cd build_cortex-m4 && make
+	
+	
+generic:
+	rm -R -f build_generic
+	mkdir build_generic
+	cd build_generic && cmake -G"Unix Makefiles" ../
+	cd build_generic && make
+	
+	
+clean:
+	rm -R -f build_bf518
+	rm -R -f build_cortex-m3
+	rm -R -f build_cortex-m4
+	rm -R -f build_generic
+
+	
\ No newline at end of file
--- /dev/null
+++ b/blockdev/filedev/ext4_filedev.c
@@ -1,0 +1,135 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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.
+ */
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+#include <ext4_errno.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+/**@brief	Default filename.*/
+const char *fname = "ext2";
+
+/**@brief	Image block size.*/
+#define EXT4_FILEDEV_BSIZE		512
+
+/**@brief	Image file descriptor.*/
+static FILE	*dev_file;
+
+
+/**********************BLOCKDEV INTERFACE**************************************/
+static int filedev_open(struct ext4_blockdev *bdev);
+static int filedev_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
+		uint32_t blk_cnt);
+static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf,
+		uint64_t blk_id, uint32_t blk_cnt);
+static int filedev_close(struct  ext4_blockdev *bdev);
+
+
+/******************************************************************************/
+EXT4_BLOCKDEV_STATIC_INSTANCE(
+		_filedev,
+		EXT4_FILEDEV_BSIZE,
+		0,
+		filedev_open,
+		filedev_bread,
+		filedev_bwrite,
+		filedev_close
+);
+
+/******************************************************************************/
+EXT4_BCACHE_STATIC_INSTANCE(__cache, 8, 1024);
+
+/******************************************************************************/
+static int filedev_open(struct ext4_blockdev *bdev)
+{
+	dev_file = fopen(fname, "r+b");
+
+	if(!dev_file)
+		return ENOENT;
+
+	if(fseek(dev_file, 0, SEEK_END))
+		return EFAULT;
+
+	_filedev.ph_bcnt = ftell(dev_file) / _filedev.ph_bsize;
+
+	return EOK;
+}
+
+/******************************************************************************/
+
+static int filedev_bread(struct  ext4_blockdev *bdev, void *buf, uint64_t blk_id,
+		uint32_t blk_cnt)
+{
+	if(fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET))
+		return EIO;
+
+	if(!fread(buf, bdev->ph_bsize * blk_cnt, 1, dev_file))
+		return EIO;
+
+	return EOK;
+}
+
+/******************************************************************************/
+static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf,
+		uint64_t blk_id, uint32_t blk_cnt)
+{
+	if(fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET))
+		return EIO;
+
+	if(!fwrite(buf, bdev->ph_bsize * blk_cnt, 1, dev_file))
+		return EIO;
+	return EOK;
+}
+
+/******************************************************************************/
+static int filedev_close(struct  ext4_blockdev *bdev)
+{
+	fclose(dev_file);
+	return EOK;
+}
+
+
+/******************************************************************************/
+
+struct	ext4_bcache* ext4_filecache_get(void)
+{
+	return &__cache;
+}
+/******************************************************************************/
+struct	ext4_blockdev* ext4_filedev_get(void)
+{
+	return &_filedev;
+}
+/******************************************************************************/
+void ext4_filedev_filename(const char *n)
+{
+	fname = n;
+}
+
+/******************************************************************************/
--- /dev/null
+++ b/blockdev/filedev/ext4_filedev.h
@@ -1,0 +1,45 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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.
+ */
+#ifndef EXT4_FILEDEV_H_
+#define EXT4_FILEDEV_H_
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**@brief	Filecache get.*/
+struct	ext4_bcache*   ext4_filecache_get(void);
+
+/**@brief	File blockdev get.*/
+struct	ext4_blockdev* ext4_filedev_get(void);
+
+void 	ext4_filedev_filename(const char *n);
+
+#endif /* EXT4_FILEDEV_H_ */
--- /dev/null
+++ b/demos/generic/main.c
@@ -1,0 +1,344 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdbool.h>
+
+#include <ext4_filedev.h>
+#include <ext4.h>
+
+
+
+char input_name[128] = "ext2";
+
+/**@brief	Read-write size*/
+static int rw_szie  = 1024;
+
+/**@brief	Read-write size*/
+static int rw_count = 1024;
+
+static bool cache_mode = false;
+
+
+/**@brief	File write buffer*/
+static uint8_t	*wr_buff;
+
+/**@brief	File read buffer.*/
+static uint8_t	*rd_buff;
+
+/**@brief	Block device handle.*/
+static struct ext4_blockdev *bd;
+
+/**@brief	Block cache handle.*/
+static struct ext4_bcache   *bc;
+
+static const char *usage = "									\n\
+Welcome in ext4 generic demo.									\n\
+Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)	\n\
+Usage:															\n\
+	-i   - input file            (default = ext2)				\n\
+	-rws - single R/W size       (default = 1024)				\n\
+	-rwc - R/W count             (default = 1024)				\n\
+	-cache - 0 static, 1 dynamic (default = 0)					\n\
+\n";
+
+static char* entry_to_str(uint8_t type)
+{
+	switch(type){
+	case EXT4_DIRENTRY_UNKNOWN:
+		return "[UNK] ";
+	case EXT4_DIRENTRY_REG_FILE:
+		return "[FIL] ";
+	case EXT4_DIRENTRY_DIR:
+		return "[DIR] ";
+	case EXT4_DIRENTRY_CHRDEV:
+		return "[CHA] ";
+	case EXT4_DIRENTRY_BLKDEV:
+		return "[BLK] ";
+	case EXT4_DIRENTRY_FIFO:
+		return "[FIF] ";
+	case EXT4_DIRENTRY_SOCK:
+		return "[SOC] ";
+	case EXT4_DIRENTRY_SYMLINK:
+		return "[SYM] ";
+	default:
+		break;
+	}
+	return "[???]";
+}
+
+static void dir_ls(const char *path)
+{
+	int j = 0;
+	char sss[255];
+	ext4_dir d;
+	ext4_direntry *de;
+
+	printf("**********************************************\n");
+
+	ext4_dir_open(&d, path);
+	de = ext4_entry_get(&d, j++);
+	printf("ls %s\n", path);
+
+	while(de){
+		memcpy(sss, de->name, de->name_length);
+		sss[de->name_length] = 0;
+		printf(entry_to_str(de->inode_type));
+		printf(sss);
+		printf("\n");
+		de = ext4_entry_get(&d, j++);
+	}
+	printf("**********************************************\n");
+	ext4_dir_close(&d);
+}
+
+static void mp_stats(void)
+{
+    struct ext4_mount_stats stats;
+    ext4_mount_point_stats("/mp/", &stats);
+
+    printf("**********************************************\n");
+    printf("ext4_mount_point_stats\n");
+    printf("inodes_count        = %d\n", stats.inodes_count);
+    printf("free_inodes_count   = %d\n", stats.free_inodes_count);
+    printf("blocks_count        = %d\n", stats.blocks_count);
+    printf("free_blocks_count   = %d\n", stats.free_blocks_count);
+    printf("block_size          = %d\n", stats.block_size);
+    printf("block_group_count   = %d\n", stats.block_group_count);
+    printf("blocks_per_group    = %d\n", stats.blocks_per_group);
+    printf("inodes_per_group    = %d\n", stats.inodes_per_group);
+    printf("volume_name         = %s\n", stats.volume_name);
+
+    printf("**********************************************\n");
+
+}
+
+static void block_stats(void)
+{
+    uint32_t i;
+
+    printf("**********************************************\n");
+    printf("ext4 blockdev stats\n");
+    printf("bdev->bread_ctr          = %d\n", bd->bread_ctr);
+    printf("bdev->bwrite_ctr         = %d\n", bd->bwrite_ctr);
+
+
+    printf("bcache->ref_blocks       = %d\n", bc->ref_blocks);
+    printf("bcache->max_ref_blocks   = %d\n", bc->max_ref_blocks);
+    printf("bcache->lru_ctr          = %d\n", bc->lru_ctr);
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->refctr[%d]     = %d\n", i, bc->refctr[i]);
+    }
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->lru_id[%d]     = %d\n", i, bc->lru_id[i]);
+    }
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->free_delay[%d] = %d\n", i, bc->free_delay[i]);
+    }
+
+    printf("\n");
+    for (i = 0; i < bc->cnt; ++i) {
+        printf("bcache->lba[%d]        = %d\n", i, bc->lba[i]);
+    }
+
+
+
+    printf("**********************************************\n");
+}
+
+
+int main(int argc, char **argv)
+{
+	int option_index = 0;
+	int	c;
+	int	r;
+	int	i;
+	uint32_t  size;
+	ext4_file f;
+
+    static struct option long_options[] =
+      {
+        {"in",     	required_argument, 0, 'a'},
+        {"rws",     required_argument, 0, 'b'},
+        {"rwc",		required_argument, 0, 'c'},
+        {"cache",   required_argument, 0, 'd'},
+        {0, 0, 0, 0}
+      };
+
+    while(-1 != (c = getopt_long (argc, argv, "a:b:c:d:", long_options, &option_index))) {
+
+    	switch(c){
+    		case 'a':
+    			strcpy(input_name, optarg);
+    			break;
+    		case 'b':
+    			rw_szie = atoi(optarg);
+    			break;
+    		case 'c':
+    			rw_count = atoi(optarg);
+    			break;
+    		case 'd':
+    			cache_mode = atoi(optarg);
+    			break;
+    		default:
+    			printf(usage);
+    			return EXIT_FAILURE;
+
+    	}
+    }
+
+    printf("Test conditions:\n");
+    printf("Imput name: %s\n", input_name);
+    printf("RW size: %d\n",  rw_szie);
+    printf("RW count: %d\n", rw_count);
+    printf("Cache mode: %s\n", cache_mode ? "dynamic" : "static");
+
+
+
+    ext4_filedev_filename(input_name);
+
+    wr_buff = malloc(rw_szie);
+    rd_buff = malloc(rw_szie);
+
+    if(!wr_buff || !rd_buff){
+    	printf("Read-Write allocation ERROR\n");
+    	return EXIT_FAILURE;
+    }
+
+	bd = ext4_filedev_get();
+	bc = ext4_filecache_get();
+
+    if(!bd || !bc){
+    	printf("Block device ERROR\n");
+    	return EXIT_FAILURE;
+    }
+
+	ext4_dmask_set(EXT4_DEBUG_ALL);
+
+	r = ext4_device_register(bd, cache_mode ? 0 : bc, "ext4_filesim");
+	if(r != EOK){
+		printf("ext4_device_register ERROR = %d\n", r);
+		return EXIT_FAILURE;
+	}
+
+	r = ext4_mount("ext4_filesim", "/mp/");
+	if(r != EOK){
+		printf("ext4_mount ERROR = %d\n", r);
+		return EXIT_FAILURE;
+	}
+
+
+	ext4_fremove("/mp/hello.txt");
+	ext4_fremove("/mp/test1");
+	mp_stats();
+	dir_ls("/mp/");
+
+    /*Add hello world file.*/
+    r = ext4_fopen(&f, "/mp/hello.txt", "wb");
+    r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0);
+    r = ext4_fclose(&f);
+
+
+	printf("ext4_fopen: test1\n");
+
+	r = ext4_fopen(&f, "/mp/test1", "wb");
+	if(r != EOK){
+		printf("ext4_fopen ERROR = %d\n", r);
+		return EXIT_FAILURE;
+	}
+
+	printf("ext4_write: %d * %d ..." , rw_count, rw_szie);
+
+	for (i = 0; i < rw_count; ++i) {
+
+		memset(wr_buff, i & 0xFF, rw_szie);
+
+		r = ext4_fwrite(&f, wr_buff, rw_szie, &size);
+
+		if((r != EOK) || (size != rw_szie))
+			break;
+	}
+
+	if(i != rw_count){
+		printf("ERROR: rw_count = %d\n", i);
+		return EXIT_FAILURE;
+	}
+
+	printf("OK\n");
+	r = ext4_fclose(&f);
+	printf("ext4_fopen: test1\n");
+
+	r = ext4_fopen(&f, "/mp/test1", "r+");
+	if(r != EOK){
+		printf("ext4_fopen ERROR = %d\n", r);
+		return EXIT_FAILURE;
+	}
+
+	printf("ext4_read: %d * %d ..." , rw_count, rw_szie);
+
+	for (i = 0; i < rw_count; ++i) {
+		memset(wr_buff, i & 0xFF, rw_szie);
+		r = ext4_fread(&f, rd_buff, rw_szie, &size);
+
+		if((r != EOK) || (size != rw_szie))
+			break;
+
+		if(memcmp(rd_buff, wr_buff, rw_szie)){
+			break;
+		}
+	}
+	if(i != rw_count){
+		printf("ERROR: rw_count = %d\n", i);
+		return EXIT_FAILURE;
+	}
+
+	printf("OK\n");
+
+	r = ext4_fclose(&f);
+
+
+	mp_stats();
+	dir_ls("/mp/");
+
+	block_stats();
+	r = ext4_umount("/mp/");
+
+	printf("Test finish: OK\n");
+    return EXIT_SUCCESS;
+
+}
--- /dev/null
+++ b/ext4.h
@@ -1,0 +1,267 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4.h
+ * @brief Ext4 high level operations (files, directories, mountpoints...).
+ * 		  Client has to include only this file.
+ */
+
+#ifndef EXT4_H_
+#define EXT4_H_
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+#include <stdint.h>
+
+/********************************FILE OPEN FLAGS********************************/
+
+#ifndef O_RDONLY
+#define O_RDONLY	00
+#endif
+
+#ifndef O_WRONLY
+#define O_WRONLY	01
+#endif
+
+#ifndef O_RDWR
+#define O_RDWR		02
+#endif
+
+#ifndef O_CREAT
+#define O_CREAT	    0100
+#endif
+
+#ifndef O_EXCL
+#define O_EXCL		0200
+#endif
+
+#ifndef O_TRUNC
+#define O_TRUNC		01000
+#endif
+
+#ifndef O_APPEND
+#define O_APPEND	02000
+#endif
+
+/********************************FILE SEEK FLAGS*****************************/
+
+#ifndef SEEK_SET
+#define SEEK_SET	0
+#endif
+
+#ifndef SEEK_CUR
+#define SEEK_CUR	1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END	2
+#endif
+
+/********************************OS LOCK INFERFACE***************************/
+
+/**@brief	OS dependent lock interface.*/
+struct ext4_lock {
+
+    /**@brief	Lock access to mountpoint*/
+    void (*lock)(void);
+
+    /**@brief	Unlock access to mountpoint*/
+    void (*unlock)(void);
+};
+
+
+/********************************FILE DESCRIPTOR*****************************/
+
+/**@brief	File descriptor*/
+typedef struct ext4_file {
+
+    /**@brief	Pountpoint handle.*/
+    struct ext4_mountpoint *mp;
+
+    /**@brief	File inode id*/
+    uint32_t inode;
+
+    /**@brief	Open flags.*/
+    uint32_t flags;
+
+    /**@brief	File size.*/
+    uint64_t fsize;
+
+    /**@brief	File position*/
+    uint64_t fpos;
+}ext4_file;
+
+/*****************************DIRECTORY DESCRIPTOR***************************/
+/**@brief	Directory entry types. Copy from ext4_types.h*/
+enum  {
+    EXT4_DIRENTRY_UNKNOWN = 0,
+    EXT4_DIRENTRY_REG_FILE,
+    EXT4_DIRENTRY_DIR,
+    EXT4_DIRENTRY_CHRDEV,
+    EXT4_DIRENTRY_BLKDEV,
+    EXT4_DIRENTRY_FIFO,
+    EXT4_DIRENTRY_SOCK,
+    EXT4_DIRENTRY_SYMLINK
+};
+
+/**@brief	Directory entry descriptor. Copy from ext4_types.h*/
+typedef struct {
+    uint32_t inode;
+    uint16_t entry_length;
+    uint8_t  name_length;
+    union {
+        uint8_t name_length_high;
+        uint8_t inode_type;
+    };
+    uint8_t name[255];
+}ext4_direntry;
+
+typedef struct  {
+    /**@brief 	File descriptor*/
+    ext4_file		f;
+    /**@brief	Current direntry.*/
+    ext4_direntry	de;
+}ext4_dir;
+
+/********************************MOUNT OPERATIONS****************************/
+
+/**@brief	Register a block device to a name.
+ *          @warning Block device has to be filled by
+ *          @ref EXT4_BLOCKDEV_STATIC_INSTANCE. Block cache may be created
+ *          @ref EXT4_BCACHE_STATIC_INSTANCE.
+ *          Block cache may by created automaticly when bc parameter is 0.
+ * @param   bd block device
+ * @param   bd block device cache (0 = automatic cache mode)
+ * @param   dev_name register name
+ * @param   standard error code*/
+int	ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
+        const char *dev_name);
+
+/**@brief	Mount a block device with EXT4 partition to the mountpoint.
+ * @param	dev_name block device name (@ref ext4_device_register)
+ * @param	mount_point pount point, for example
+ *          -   /
+ *          -   /my_partition/
+ *          -   /my_second_partition/
+ *
+ * @return standard error code */
+int	ext4_mount(const char * dev_name,  char *mount_point);
+
+/**@brief	Umount operation.
+ * @param	mount_point mount name
+ * @return  standard error code */
+int	ext4_umount(char *mount_point);
+
+
+/**@brief   Some of the filesystem params.*/
+struct ext4_mount_stats {
+    uint32_t inodes_count;
+    uint32_t free_inodes_count;
+    uint64_t blocks_count;
+    uint64_t free_blocks_count;
+
+    uint32_t block_size;
+    uint32_t block_group_count;
+    uint32_t blocks_per_group;
+    uint32_t inodes_per_group;
+
+    char volume_name[16];
+};
+
+int ext4_mount_point_stats(const char *mount_point,
+    struct ext4_mount_stats *stats);
+
+/********************************FILE OPERATIONS*****************************/
+
+/**@brief	*/
+int ext4_fremove(const char *path);
+
+/**@brief	File open function.
+ * @param	filename, (has to start from mountpoint)
+ * 			/my_partition/my_file
+ * @param	flags open file flags
+ *  |---------------------------------------------------------------|
+ *  |   r or rb                 O_RDONLY                            |
+ *  |---------------------------------------------------------------|
+ *  |   w or wb                 O_WRONLY|O_CREAT|O_TRUNC            |
+ *  |---------------------------------------------------------------|
+ *  |   a or ab                 O_WRONLY|O_CREAT|O_APPEND           |
+ *  |---------------------------------------------------------------|
+ *  |   r+ or rb+ or r+b        O_RDWR                              |
+ *  |---------------------------------------------------------------|
+ *  |   w+ or wb+ or w+b        O_RDWR|O_CREAT|O_TRUNC              |
+ *  |---------------------------------------------------------------|
+ *  |   a+ or ab+ or a+b        O_RDWR|O_CREAT|O_APPEND             |
+ *  |---------------------------------------------------------------|
+ *
+ * @return	standard error code*/
+int ext4_fopen (ext4_file *f, const char *path, const char *flags);
+
+/**@brief	*/
+int ext4_fclose(ext4_file *f);
+
+/**@brief	*/
+int ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt);
+
+/**@brief	*/
+int ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt);
+
+/**@brief	*/
+int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin);
+
+/**@brief	*/
+uint64_t ext4_ftell (ext4_file *f);
+
+/**@brief	*/
+uint64_t ext4_fsize (ext4_file *f);
+
+/*********************************DIRECTORY OPERATION***********************/
+/**@brief	*/
+int ext4_mkdir(const char *path);
+
+/**@brief	*/
+int ext4_rmdir(const char *path);
+
+/**@brief	*/
+int ext4_dir_open (ext4_dir *d, const char *path);
+
+/**@brief	*/
+int ext4_dir_close(ext4_dir *d);
+
+/**@brief	*/
+ext4_direntry* ext4_entry_get(ext4_dir *d, uint32_t id);
+
+#endif /* EXT4_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4.c
@@ -1,0 +1,1205 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4.h
+ * @brief Ext4 high level operations (file, directory, mountpoints...)
+ */
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+#include <ext4_types.h>
+#include <ext4_debug.h>
+#include <ext4_errno.h>
+#include <ext4_fs.h>
+#include <ext4_dir.h>
+#include <ext4_inode.h>
+#include <ext4_super.h>
+#include <ext4_dir_idx.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <ext4.h>
+
+/**@brief	Mount point OS dependent lock*/
+#define EXT4_MP_LOCK(_m)    \
+        do { (_m)->os_locks ? (_m)->os_locks->lock()   : 0; }while(0)
+
+/**@brief	Mount point OS dependent unlock*/
+#define EXT4_MP_UNLOCK(_m)  \
+        do { (_m)->os_locks ? (_m)->os_locks->unlock() : 0;	}while(0)
+
+/**@brief	Mount point descrpitor.*/
+struct ext4_mountpoint {
+
+    /**@brief	Mount point name (@ref ext4_mount)*/
+    const char 		 *name;
+
+    /**@brief	Os dependent lock/unlock functions.*/
+    struct ext4_lock *os_locks;
+
+    /**@brief	Ext4 filesystem internals.*/
+    struct ext4_fs	 fs;
+
+    /**@brief	Dynamic alocation cache flag.*/
+    bool            cache_dynamic;
+};
+
+/**@brief	Block devices descriptor.*/
+struct	_ext4_devices {
+
+    /**@brief	Block device name (@ref ext4_device_register)*/
+    const char				*name;
+
+    /**@brief	Block device handle.*/
+    struct ext4_blockdev	*bd;
+
+    /**@brief	Block cache handle.*/
+    struct ext4_bcache		*bc;
+};
+
+/**@brief	Block devices.*/
+struct	_ext4_devices _bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT];
+
+
+/**@brief	Mountpoints.*/
+struct ext4_mountpoint	_mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];
+
+
+
+int	ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
+        const char *dev_name)
+{
+    uint32_t i;
+    ext4_assert(bd && dev_name);
+
+    for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
+        if(!_bdevices[i].name){
+            _bdevices[i].name   = dev_name;
+            _bdevices[i].bd 	= bd;
+            _bdevices[i].bc 	= bc;
+            return EOK;
+        }
+    }
+    return ENOSPC;
+}
+
+/****************************************************************************/
+
+
+static bool ext4_is_dots(const uint8_t *name, size_t name_size)
+{
+    if ((name_size == 1) && (name[0] == '.'))
+        return true;
+
+    if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))
+        return true;
+
+    return false;
+}
+
+static int ext4_has_children(bool *has_children, struct ext4_inode_ref *enode)
+{
+
+    struct ext4_fs *fs = enode->fs;
+
+    /* Check if node is directory */
+    if (!ext4_inode_is_type(&fs->sb, enode->inode,
+            EXT4_INODE_MODE_DIRECTORY)) {
+        *has_children = false;
+        return EOK;
+    }
+
+    struct ext4_directory_iterator it;
+    int rc = ext4_dir_iterator_init(&it, enode, 0);
+    if (rc != EOK)
+        return rc;
+
+    /* Find a non-empty directory entry */
+    bool found = false;
+    while (it.current != NULL) {
+        if (it.current->inode != 0) {
+            uint16_t name_size =
+                    ext4_dir_entry_ll_get_name_length(&fs->sb,
+                            it.current);
+            if (!ext4_is_dots(it.current->name, name_size)) {
+                found = true;
+                break;
+            }
+        }
+
+        rc = ext4_dir_iterator_next(&it);
+        if (rc != EOK) {
+            ext4_dir_iterator_fini(&it);
+            return rc;
+        }
+    }
+
+    rc = ext4_dir_iterator_fini(&it);
+    if (rc != EOK)
+        return rc;
+
+    *has_children = found;
+
+    return EOK;
+}
+
+
+static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,
+        struct ext4_inode_ref *child, const char *name, uint32_t name_len)
+{
+    /* Check maximum name length */
+    if(name_len > EXT4_DIRECTORY_FILENAME_LEN)
+        return EINVAL;
+
+    /* Add entry to parent directory */
+    int rc = ext4_dir_add_entry(parent, name, name_len,
+            child);
+    if (rc != EOK)
+        return rc;
+
+    /* Fill new dir -> add '.' and '..' entries */
+    if (ext4_inode_is_type(&mp->fs.sb, child->inode,
+            EXT4_INODE_MODE_DIRECTORY)) {
+        rc = ext4_dir_add_entry(child, ".", strlen("."),
+                child);
+        if (rc != EOK) {
+            ext4_dir_remove_entry(parent, name, strlen(name));
+            return rc;
+        }
+
+        rc = ext4_dir_add_entry(child, "..", strlen(".."),
+                parent);
+        if (rc != EOK) {
+            ext4_dir_remove_entry(parent, name, strlen(name));
+            ext4_dir_remove_entry(child, ".", strlen("."));
+            return rc;
+        }
+
+#if CONFIG_DIR_INDEX_ENABLE
+        /* Initialize directory index if supported */
+        if (ext4_sb_check_feature_compatible(&mp->fs.sb,
+                EXT4_FEATURE_COMPAT_DIR_INDEX)) {
+            rc = ext4_dir_dx_init(child);
+            if (rc != EOK)
+                return rc;
+
+            ext4_inode_set_flag(child->inode,
+                    EXT4_INODE_FLAG_INDEX);
+            child->dirty = true;
+        }
+#endif
+
+        uint16_t parent_links =
+                ext4_inode_get_links_count(parent->inode);
+        parent_links++;
+        ext4_inode_set_links_count(parent->inode, parent_links);
+
+        parent->dirty = true;
+    }
+
+    uint16_t child_links =
+            ext4_inode_get_links_count(child->inode);
+    child_links++;
+    ext4_inode_set_links_count(child->inode, child_links);
+
+    child->dirty = true;
+
+    return EOK;
+}
+
+static int ext4_unlink(struct ext4_mountpoint *mp,
+    struct ext4_inode_ref *parent, struct ext4_inode_ref *child_inode_ref,
+    const char *name, uint32_t name_len)
+{
+    bool has_children;
+    int rc = ext4_has_children(&has_children, child_inode_ref);
+    if (rc != EOK)
+        return rc;
+
+    /* Cannot unlink non-empty node */
+    if (has_children)
+        return ENOTSUP;
+
+    /* Remove entry from parent directory */
+
+    rc = ext4_dir_remove_entry(parent, name, name_len);
+    if (rc != EOK)
+        return rc;
+
+
+    uint32_t lnk_count =
+            ext4_inode_get_links_count(child_inode_ref->inode);
+    lnk_count--;
+
+    bool is_dir = ext4_inode_is_type(&mp->fs.sb, child_inode_ref->inode,
+            EXT4_INODE_MODE_DIRECTORY);
+
+    /* If directory - handle links from parent */
+    if ((lnk_count <= 1) && (is_dir)) {
+        ext4_assert(lnk_count == 1);
+
+        lnk_count--;
+
+        uint32_t parent_lnk_count = ext4_inode_get_links_count(
+                parent->inode);
+
+        parent_lnk_count--;
+        ext4_inode_set_links_count(parent->inode, parent_lnk_count);
+
+        parent->dirty = true;
+    }
+
+    /*
+     * TODO: Update timestamps of the parent
+     * (when we have wall-clock time).
+     *
+     * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);
+     * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);
+     * parent->dirty = true;
+     */
+
+    /*
+     * TODO: Update timestamp for inode.
+     *
+     * ext4_inode_set_change_inode_time(child_inode_ref->inode,
+     *     (uint32_t) now);
+     */
+
+    ext4_inode_set_deletion_time(child_inode_ref->inode, 1);
+    ext4_inode_set_links_count(child_inode_ref->inode, lnk_count);
+    child_inode_ref->dirty = true;
+
+    return EOK;
+}
+
+/****************************************************************************/
+
+int			ext4_mount(const char * dev_name,  char *mount_point)
+{
+    ext4_assert(mount_point && dev_name);
+    int r = EOK;
+    int i;
+
+    uint32_t bsize;
+    struct ext4_blockdev	*bd = 0;
+    struct ext4_bcache		*bc = 0;
+    struct ext4_mountpoint	*mp = 0;
+
+    if(mount_point[strlen(mount_point) - 1] != '/')
+        return ENOTSUP;
+
+    for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
+        if(_bdevices[i].name){
+            if(!strcmp(dev_name, _bdevices[i].name)){
+                bd = _bdevices[i].bd;
+                bc = _bdevices[i].bc;
+                break;
+            }
+        }
+    }
+
+    if(!bd)
+        return ENODEV;
+
+    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+        if(!_mp[i].name){
+            _mp[i].name = mount_point;
+            mp = &_mp[i];
+            break;
+        }
+    }
+
+    if(!mp)
+        return ENOMEM;
+
+    r = ext4_block_init(bd);
+    if(r != EOK)
+        return r;
+
+    r = ext4_fs_init(&mp->fs, bd);
+    if(r != EOK){
+        ext4_block_fini(bd);
+        return r;
+    }
+
+    bsize = ext4_sb_get_block_size(&mp->fs.sb);
+    ext4_block_set_lb_size(bd, bsize);
+
+
+    mp->cache_dynamic = 0;
+
+    if(!bc){
+        /*Automatic block cache alloc.*/
+        mp->cache_dynamic = 1;
+        bc = malloc(sizeof(struct ext4_bcache));
+
+        r = ext4_bcache_init_dynamic(bc, 8, bsize);
+        if(r != EOK){
+            free(bc);
+            ext4_block_fini(bd);
+            return r;
+        }
+    }
+
+    if(bsize != bc->itemsize)
+        return ENOTSUP;
+
+
+    /*Bind block cache to block device*/
+    r = ext4_block_bind_bcache(bd, bc);
+    if(r != EOK){
+        ext4_block_fini(bd);
+        if(mp->cache_dynamic){
+            ext4_bcache_fini_dynamic(bc);
+            free(bc);
+        }
+        return r;
+    }
+
+    return r;
+}
+
+
+int			ext4_umount(char *mount_point)
+{
+    int 	i;
+    int 	r = EOK;
+    struct ext4_mountpoint	*mp = 0;
+
+    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+        if(_mp[i].name){
+            if(!strcmp(_mp[i].name, mount_point))
+                mp = &_mp[i];
+            break;
+        }
+    }
+
+    if(!mp)
+        return ENODEV;
+
+    r = ext4_fs_fini(&mp->fs);
+    if(r != EOK)
+        return r;
+
+    mp->name = 0;
+
+    if(mp->cache_dynamic){
+        ext4_bcache_fini_dynamic(mp->fs.bdev->bc);
+        free(mp->fs.bdev->bc);
+    }
+
+    return ext4_block_fini(mp->fs.bdev);
+}
+
+int ext4_mount_point_stats(const char *mount_point,
+    struct ext4_mount_stats *stats)
+{
+    uint32_t i;
+    struct ext4_mountpoint    *mp = 0;
+
+    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+        if(_mp[i].name){
+            if(!strcmp(_mp[i].name, mount_point))
+                mp = &_mp[i];
+            break;
+        }
+    }
+
+    if(!mp)
+        return ENOENT;
+
+
+    EXT4_MP_LOCK(mp);
+    stats->inodes_count      = ext4_get32(&mp->fs.sb, inodes_count);
+    stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);
+    stats->blocks_count      = ext4_sb_get_blocks_cnt(&mp->fs.sb);
+    stats->free_blocks_count = ext4_sb_get_free_blocks_cnt(&mp->fs.sb);
+    stats->block_size        = ext4_sb_get_block_size(&mp->fs.sb);
+
+    stats->block_group_count = ext4_block_group_cnt(&mp->fs.sb);
+    stats->blocks_per_group  = ext4_get32(&mp->fs.sb, blocks_per_group);
+    stats->inodes_per_group  = ext4_get32(&mp->fs.sb, inodes_per_group);
+
+    memcpy(stats->volume_name, mp->fs.sb.volume_name, 16);
+    EXT4_MP_UNLOCK(mp);
+
+    return EOK;
+}
+
+/********************************FILE OPERATIONS*****************************/
+
+static struct ext4_mountpoint*  ext4_get_mount(const char *path)
+{
+    int i;
+    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
+        if(_mp[i].name){
+            if(!strncmp(_mp[i].name, path, strlen(_mp[i].name)))
+                return &_mp[i];
+        }
+    }
+    return 0;
+}
+
+
+static int ext4_path_check(const char *path, bool* is_goal)
+{
+    int i;
+
+    for (i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {
+
+        if(path[i] == '/'){
+            *is_goal = false;
+            return i;
+        }
+
+        if(path[i] == 0){
+            *is_goal = true;
+            return i;
+        }
+    }
+
+    return 0;
+}
+
+
+static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
+{
+    if(!flags)
+        return false;
+
+    if(!strcmp(flags, "r") || !strcmp(flags, "rb")){
+        *file_flags = O_RDONLY;
+        return true;
+    }
+
+    if(!strcmp(flags, "w") || !strcmp(flags, "wb")){
+        *file_flags = O_WRONLY | O_CREAT | O_TRUNC;
+        return true;
+    }
+
+    if(!strcmp(flags, "a") || !strcmp(flags, "ab")){
+        *file_flags = O_WRONLY | O_CREAT | O_APPEND	;
+        return true;
+    }
+
+    if(!strcmp(flags, "r+") || !strcmp(flags, "rb+") || !strcmp(flags, "r+b")){
+        *file_flags = O_RDWR;
+        return true;
+    }
+
+    if(!strcmp(flags, "w+") || !strcmp(flags, "wb+") || !strcmp(flags, "w+b")){
+        *file_flags = O_RDWR | O_CREAT | O_TRUNC;
+        return true;
+    }
+
+    if(!strcmp(flags, "a+") || !strcmp(flags, "ab+") || !strcmp(flags, "a+b")){
+        *file_flags = O_RDWR | O_CREAT | O_APPEND;
+        return true;
+    }
+
+    return false;
+}
+
+/****************************************************************************/
+
+static int ext4_generic_open (ext4_file *f, const char *path,
+        const char *flags, bool file_expect)
+{
+    struct ext4_mountpoint *mp = ext4_get_mount(path);
+    struct ext4_directory_search_result result;
+    struct ext4_inode_ref	ref;
+    bool	is_goal = false;
+    uint8_t	inode_type;
+    int		r = ENOENT;
+    uint32_t next_inode;
+
+    f->mp = 0;
+
+    if(!mp)
+        return ENOENT;
+
+    if(ext4_parse_flags(flags, &f->flags) == false)
+        return EINVAL;
+
+    /*Skip mount point*/
+    path += strlen(mp->name);
+
+    EXT4_MP_LOCK(mp);
+
+    /*Load root*/
+    r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
+
+    if(r != EOK)
+        return r;
+
+    int len = ext4_path_check(path, &is_goal);
+
+    /*If root open was request.*/
+    if(!len && is_goal)
+        goto IsGoal;
+
+    while(1){
+
+        len = ext4_path_check(path, &is_goal);
+
+        if(!len){
+            r = ENOENT;
+            break;
+        }
+
+        r = ext4_dir_find_entry(&result, &ref, path, len);
+        if(r != EOK){
+
+            if(r != ENOENT)
+                break;
+
+            if(!(f->flags & O_CREAT))
+                break;
+
+            /*O_CREAT allows to create new entry*/
+            struct ext4_inode_ref	child_ref;
+            r = ext4_fs_alloc_inode(&mp->fs, &child_ref, !is_goal);
+            if(r != EOK)
+                break;
+
+            /*Destroy last result*/
+            ext4_dir_destroy_result(&ref, &result);
+
+            /*Link with root dir.*/
+            r = ext4_link(mp, &ref, &child_ref, path, len);
+            if(r != EOK){
+                /*Fali. Free new inode.*/
+                ext4_fs_free_inode(&child_ref);
+                /*We do not want to write new inode.
+                  But block has to be released.*/
+                child_ref.dirty = false;
+                ext4_fs_put_inode_ref(&child_ref);
+                break;
+            }
+
+            ext4_fs_put_inode_ref(&child_ref);
+
+            continue;
+        }
+
+        next_inode = result.dentry->inode;
+        inode_type = ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
+
+        r = ext4_dir_destroy_result(&ref, &result);
+        if(r != EOK)
+            break;
+
+        /*If expected file error*/
+        if((inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE)
+                && !file_expect && is_goal){
+            r = ENOENT;
+            break;
+        }
+
+        /*If expected directory error*/
+        if((inode_type == EXT4_DIRECTORY_FILETYPE_DIR)
+                && file_expect && is_goal){
+            r = ENOENT;
+            break;
+        }
+
+        r = ext4_fs_put_inode_ref(&ref);
+        if(r != EOK)
+            break;
+
+        r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &ref);
+        if(r != EOK)
+            break;
+
+        if(is_goal)
+            break;
+
+        path += len + 1;
+    };
+
+    if(r != EOK){
+        ext4_fs_put_inode_ref(&ref);
+        EXT4_MP_UNLOCK(mp);
+        return r;
+    }
+
+    IsGoal:
+    if(is_goal){
+
+        if(f->flags & O_TRUNC){
+            /*Turncate.*/
+            ext4_block_delay_cache_flush(mp->fs.bdev, 1);
+            /*Truncate may be IO heavy.
+             Do it with delayed cache flush mode.*/
+            r = ext4_fs_truncate_inode(&ref, 0);
+            ext4_block_delay_cache_flush(mp->fs.bdev, 0);
+
+            if(r != EOK){
+                ext4_fs_put_inode_ref(&ref);
+                EXT4_MP_UNLOCK(mp);
+                return r;
+            }
+        }
+
+        f->mp = mp;
+        f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+        f->inode = ref.index;
+        f->fpos  = 0;
+
+        if(f->flags & O_APPEND)
+            f->fpos = f->fsize;
+
+    }
+
+    r = ext4_fs_put_inode_ref(&ref);
+    EXT4_MP_UNLOCK(mp);
+    return r;
+}
+
+/****************************************************************************/
+
+int ext4_fremove(const char *path)
+{
+    struct ext4_mountpoint *mp = ext4_get_mount(path);
+    struct ext4_directory_search_result result;
+    bool	is_goal = false;
+    uint8_t	inode_type;
+    int		r = ENOENT;
+    uint32_t next_inode;
+
+    struct ext4_inode_ref	parent;
+    struct ext4_inode_ref	child;
+    int len = 0;
+
+    if(!mp)
+        return ENOENT;
+
+
+    /*Skip mount point*/
+    path += strlen(mp->name);
+
+    /*Lock mountpoint*/
+    EXT4_MP_LOCK(mp);
+
+    /*Load root*/
+    r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &parent);
+
+    if(r != EOK){
+        EXT4_MP_UNLOCK(mp);
+        return r;
+    }
+
+    while(1){
+
+        len = ext4_path_check(path, &is_goal);
+
+        if(!len){
+            r = ENOENT;
+            break;
+        }
+
+        r = ext4_dir_find_entry(&result, &parent, path, len);
+        if(r != EOK){
+            ext4_dir_destroy_result(&parent, &result);
+            break;
+        }
+
+        next_inode = result.dentry->inode;
+        inode_type = ext4_dir_entry_ll_get_inode_type(&mp->fs.sb,
+                result.dentry);
+
+        r = ext4_dir_destroy_result(&parent, &result);
+        if(r != EOK)
+            break;
+
+        /*If expected file error*/
+        if((inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE) && !is_goal){
+            r = ENOENT;
+            break;
+        }
+
+        /*If expected directory error*/
+        if((inode_type == EXT4_DIRECTORY_FILETYPE_DIR) && is_goal){
+            r = ENOENT;
+            break;
+        }
+
+        if(is_goal)
+            break;
+
+        r = ext4_fs_put_inode_ref(&parent);
+        if(r != EOK)
+            break;
+
+
+        r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &parent);
+        if(r != EOK)
+            break;
+
+        path += len + 1;
+    };
+
+    if(r != EOK){
+        /*No entry or other error.*/
+        ext4_fs_put_inode_ref(&parent);
+        EXT4_MP_UNLOCK(mp);
+        return r;
+    }
+
+
+    /*We have file to delete. Load it.*/
+    r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &child);
+    if(r != EOK){
+        /*Parent free*/
+        ext4_fs_put_inode_ref(&parent);
+        EXT4_MP_UNLOCK(mp);
+        return r;
+    }
+
+    /*Turncate.*/
+    ext4_block_delay_cache_flush(mp->fs.bdev, 1);
+
+    /*Truncate may be IO heavy. Do it with delayed cache flush mode.*/
+    r = ext4_fs_truncate_inode(&child, 0);
+
+    ext4_block_delay_cache_flush(mp->fs.bdev, 0);
+    if(r != EOK)
+        goto Finish;
+
+    /*Unlink from parent.*/
+    r = ext4_unlink(mp, &parent, &child, path, len);
+    if(r != EOK)
+        goto Finish;
+
+    r = ext4_fs_free_inode(&child);
+    if(r != EOK)
+        goto Finish;
+
+
+    Finish:
+    ext4_fs_put_inode_ref(&child);
+    ext4_fs_put_inode_ref(&parent);
+    EXT4_MP_UNLOCK(mp);
+    return r;
+}
+
+
+int	ext4_fopen (ext4_file *f, const char *path, const char *flags)
+{
+    return ext4_generic_open(f, path, flags, true);
+}
+
+int	ext4_fclose(ext4_file *f)
+{
+    ext4_assert(f && f->mp);
+
+    f->mp    = 0;
+    f->flags = 0;
+    f->inode = 0;
+    f->fpos  = f->fsize = 0;
+
+    return EOK;
+}
+int	ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)
+{
+    int		 r = EOK;
+    uint32_t u;
+    uint32_t fblock;
+    struct ext4_block b;
+    uint8_t	*u8_buf = buf;
+    struct ext4_inode_ref ref;
+    uint32_t sblock;
+    uint32_t block_size;
+
+    ext4_assert(f && f->mp);
+
+    if(f->flags & O_WRONLY)
+        return EPERM;
+
+    if(!size)
+        return EOK;
+
+    EXT4_MP_LOCK(f->mp);
+
+    if(rcnt)
+        *rcnt = 0;
+
+    r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
+    if(r != EOK){
+        EXT4_MP_UNLOCK(f->mp);
+        return r;
+    }
+
+    /*Sync file size*/
+    f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+
+
+    block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
+    size = size > (f->fsize - f->fpos) ? (f->fsize - f->fpos) : size;
+
+    sblock 	= (f->fpos) / block_size;
+
+    u = (f->fpos) % block_size;
+
+
+    if(u){
+
+        uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
+
+        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+        if(r != EOK)
+            goto Finish;
+
+        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+        if(r != EOK)
+            goto Finish;
+
+        memcpy(u8_buf, b.data + u, ll);
+
+        r = ext4_block_set(f->mp->fs.bdev, &b);
+        if(r != EOK)
+            goto Finish;
+
+        u8_buf  += ll;
+        size    -= ll;
+        f->fpos += ll;
+
+        if(rcnt)
+            *rcnt += ll;
+
+        sblock++;
+    }
+
+    while(size >= block_size){
+
+        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+        if(r != EOK)
+            goto Finish;
+
+        r = ext4_block_get_direct(f->mp->fs.bdev, u8_buf, fblock);
+        if(r != EOK)
+            goto Finish;
+
+
+        u8_buf  += block_size;
+        size    -= block_size;
+        f->fpos += block_size;
+
+        if(rcnt)
+            *rcnt += block_size;
+
+        sblock++;
+    }
+
+    if(size){
+        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+        if(r != EOK)
+            goto Finish;
+
+        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+        if(r != EOK)
+            goto Finish;
+
+        memcpy(u8_buf, b.data , size);
+
+        r = ext4_block_set(f->mp->fs.bdev, &b);
+        if(r != EOK)
+            goto Finish;
+
+        f->fpos += size;
+
+        if(rcnt)
+            *rcnt += size;
+    }
+
+    Finish:
+    ext4_fs_put_inode_ref(&ref);
+    EXT4_MP_UNLOCK(f->mp);
+    return r;
+}
+
+int	ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt)
+{
+    int		 r = EOK;
+    uint32_t u;
+    uint32_t fblock;
+    struct ext4_block b;
+    uint8_t	*u8_buf = buf;
+    struct ext4_inode_ref ref;
+    uint32_t sblock;
+    uint32_t file_blocks;
+    uint32_t block_size;
+
+    ext4_assert(f && f->mp);
+
+    if(f->flags & O_RDONLY)
+        return EPERM;
+
+    if(!size)
+        return EOK;
+
+    EXT4_MP_LOCK(f->mp);
+
+    if(wcnt)
+        *wcnt = 0;
+
+    r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
+    if(r != EOK){
+        EXT4_MP_UNLOCK(f->mp);
+        return r;
+    }
+
+    /*Sync file size*/
+    f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
+
+    block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
+
+    file_blocks = (f->fsize / block_size);
+
+    if(f->fsize % block_size)
+        file_blocks++;
+
+    sblock 	= (f->fpos) / block_size;
+
+    u = (f->fpos) % block_size;
+
+
+    if(u){
+        uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
+
+        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+        if(r != EOK)
+            goto Finish;
+
+        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+        if(r != EOK)
+            goto Finish;
+
+        memcpy(b.data + u, u8_buf, ll);
+        b.dirty = true;
+
+        r = ext4_block_set(f->mp->fs.bdev, &b);
+        if(r != EOK)
+            goto Finish;
+
+        u8_buf  += ll;
+        size    -= ll;
+        f->fpos += ll;
+
+        if(wcnt)
+            *wcnt += ll;
+
+        sblock++;
+    }
+
+
+    /*Start delay cache flush mode.*/
+    r = ext4_block_delay_cache_flush(f->mp->fs.bdev, 1);
+    if(r != EOK)
+        goto Finish;
+
+    while(size >= block_size){
+
+        if(sblock < file_blocks){
+            r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+            if(r != EOK)
+                break;
+        }
+        else {
+            r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
+            if(r != EOK)
+                break;
+        }
+
+        r = ext4_block_set_direct(f->mp->fs.bdev, u8_buf, fblock);
+        if(r != EOK)
+            break;
+
+        u8_buf  += block_size;
+        size    -= block_size;
+        f->fpos += block_size;
+
+        if(wcnt)
+            *wcnt += block_size;
+
+        sblock++;
+    }
+
+    /*Stop delay cache flush mode*/
+    ext4_block_delay_cache_flush(f->mp->fs.bdev, 0);
+
+    if(r != EOK)
+        goto Finish;
+
+    if(size){
+        if(sblock < file_blocks){
+            r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
+            if(r != EOK)
+                goto Finish;
+        }
+        else {
+            r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
+            if(r != EOK)
+                goto Finish;
+        }
+
+        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
+        if(r != EOK)
+            goto Finish;
+
+        memcpy(b.data, u8_buf , size);
+        b.dirty = true;
+
+        r = ext4_block_set(f->mp->fs.bdev, &b);
+        if(r != EOK)
+            goto Finish;
+
+        f->fpos += size;
+
+        if(wcnt)
+            *wcnt += size;
+    }
+
+    if(f->fpos > f->fsize){
+        f->fsize = f->fpos;
+        ext4_inode_set_size(ref.inode, f->fsize);
+        ref.dirty = true;
+    }
+
+    Finish:
+    ext4_fs_put_inode_ref(&ref);
+    EXT4_MP_UNLOCK(f->mp);
+    return r;
+
+}
+
+
+
+int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin)
+{
+    switch(origin){
+    case SEEK_SET:
+
+        if(offset > f->fsize)
+            return EINVAL;
+
+        f->fpos = offset;
+        return EOK;
+    case SEEK_CUR:
+        if((offset + f->fpos) > f->fsize)
+            return EINVAL;
+
+        f->fpos += offset;
+        return EOK;
+    case SEEK_END:
+        if(offset > f->fsize)
+            return EINVAL;
+        f->fpos = f->fsize - offset;
+        return EOK;
+
+    }
+
+    return EINVAL;
+}
+
+uint64_t ext4_ftell (ext4_file *f)
+{
+    return  f->fpos;
+}
+
+uint64_t ext4_fsize (ext4_file *f)
+{
+    return  f->fsize;
+}
+
+/*********************************DIRECTORY OPERATION************************/
+
+int	ext4_dir_open (ext4_dir *d, const char *path)
+{
+    return ext4_generic_open(&d->f, path, "r", false);
+}
+
+int	ext4_dir_close(ext4_dir *d)
+{
+    return ext4_fclose(&d->f);
+}
+
+ext4_direntry*	ext4_entry_get(ext4_dir *d, uint32_t id)
+{
+    int 	 r;
+    uint32_t i;
+    ext4_direntry *de = 0;
+    struct ext4_inode_ref dir;
+    struct ext4_directory_iterator it;
+
+    EXT4_MP_LOCK(d->f.mp);
+
+    r = ext4_fs_get_inode_ref(&d->f.mp->fs, d->f.inode, &dir);
+    if(r != EOK){
+        goto Finish;
+    }
+
+    r = ext4_dir_iterator_init(&it, &dir, 0);
+    if(r != EOK){
+        ext4_fs_put_inode_ref(&dir);
+        goto Finish;
+    }
+
+    i = 0;
+    while(r == EOK){
+
+        if(!it.current)
+            break;
+
+        if(i == id){
+            memcpy(&d->de, it.current, sizeof(ext4_direntry));
+            de = &d->de;
+            break;
+        }
+
+
+        i++;
+        r = ext4_dir_iterator_next(&it);
+    }
+
+    ext4_dir_iterator_fini(&it);
+    ext4_fs_put_inode_ref(&dir);
+
+    Finish:
+    EXT4_MP_UNLOCK(d->f.mp);
+    return de;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_balloc.c
@@ -1,0 +1,609 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_balloc.c
+ * @brief Physical block allocator.
+ */
+
+#include <ext4_config.h>
+#include <ext4_balloc.h>
+#include <ext4_super.h>
+#include <ext4_block_group.h>
+#include <ext4_fs.h>
+#include <ext4_bitmap.h>
+#include <ext4_inode.h>
+
+
+
+static uint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s,
+    uint32_t baddr)
+{
+    if(ext4_get32(s, first_data_block))
+        baddr--;
+
+    return baddr / ext4_get32(s, blocks_per_group);
+}
+
+
+uint32_t ext4_balloc_get_first_data_block_in_group(struct ext4_sblock *s,
+    struct ext4_block_group_ref * bg_ref)
+{
+    uint32_t block_group_count 		 = ext4_block_group_cnt(s);
+    uint32_t inode_table_first_block =
+            ext4_bg_get_inode_table_first_block(bg_ref->block_group, s);
+    uint32_t block_size 			 = ext4_sb_get_block_size(s);
+
+    uint16_t inode_size 	  = ext4_get16(s, inode_size);
+    uint32_t inodes_per_group = ext4_get32(s, inodes_per_group);
+
+    uint32_t inode_table_bytes;
+
+
+    if (bg_ref->index < block_group_count - 1) {
+        inode_table_bytes = inodes_per_group * inode_size;
+    } else {
+        /* Last block group could be smaller */
+        uint32_t inodes_count_total =	ext4_get32(s, inodes_count);
+        inode_table_bytes =
+                (inodes_count_total - ((block_group_count - 1) *
+                        inodes_per_group)) * inode_size;
+    }
+
+    uint32_t inode_table_blocks = inode_table_bytes / block_size;
+
+    if (inode_table_bytes % block_size)
+        inode_table_blocks++;
+
+    return inode_table_first_block + inode_table_blocks;
+}
+
+int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, uint32_t baddr)
+{
+    struct ext4_fs 	     *fs   = inode_ref->fs;
+    struct ext4_sblock   *sb   = &fs->sb;
+
+
+    uint32_t block_group    = ext4_balloc_get_bgid_of_block(sb, baddr);
+    uint32_t index_in_group	= ext4_fs_baddr2_index_in_group(sb, baddr);
+
+    /* Load block group reference */
+    struct ext4_block_group_ref bg_ref;
+    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    /* Load block with bitmap */
+    uint32_t bitmap_block_addr =
+            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
+
+    struct	ext4_block bitmap_block;
+
+    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Modify bitmap */
+    ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
+    bitmap_block.dirty = true;
+
+    /* Release block with bitmap */
+    rc = ext4_block_set(fs->bdev, &bitmap_block);
+    if (rc != EOK) {
+        /* Error in saving bitmap */
+        ext4_fs_put_block_group_ref(&bg_ref);
+        return rc;
+    }
+
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+
+    /* Update superblock free blocks count */
+    uint64_t sb_free_blocks =
+            ext4_sb_get_free_blocks_cnt(sb);
+    sb_free_blocks++;
+    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
+
+    /* Update inode blocks count */
+    uint64_t ino_blocks =
+            ext4_inode_get_blocks_count(sb, inode_ref->inode);
+    ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE;
+    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
+    inode_ref->dirty = true;
+
+    /* Update block group free blocks count */
+    uint32_t free_blocks =
+            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
+    free_blocks++;
+    ext4_bg_set_free_blocks_count(bg_ref.block_group,
+        sb, free_blocks);
+
+    bg_ref.dirty = true;
+
+    /* Release block group reference */
+    rc = ext4_fs_put_block_group_ref(&bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    return EOK;
+}
+
+int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first,
+    uint32_t count)
+{
+    struct ext4_fs *fs = inode_ref->fs;
+    struct ext4_sblock *sb = &fs->sb;
+
+    /* Compute indexes */
+    uint32_t block_group_first =
+            ext4_balloc_get_bgid_of_block(sb, first);
+    uint32_t block_group_last =
+            ext4_balloc_get_bgid_of_block(sb, first + count - 1);
+
+    ext4_assert(block_group_first == block_group_last);
+
+    /* Load block group reference */
+    struct ext4_block_group_ref bg_ref;
+    int rc = ext4_fs_get_block_group_ref(fs, block_group_first, &bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    uint32_t index_in_group_first =
+            ext4_fs_baddr2_index_in_group(sb, first);
+
+    /* Load block with bitmap */
+    uint32_t bitmap_block_addr =
+            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
+
+    struct	ext4_block bitmap_block;
+
+    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Modify bitmap */
+    ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, count);
+    bitmap_block.dirty = true;
+
+    /* Release block with bitmap */
+    rc = ext4_block_set(fs->bdev, &bitmap_block);
+    if (rc != EOK) {
+        ext4_fs_put_block_group_ref(&bg_ref);
+        return rc;
+    }
+
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+
+    /* Update superblock free blocks count */
+    uint64_t sb_free_blocks =
+            ext4_sb_get_free_blocks_cnt(sb);
+    sb_free_blocks += count;
+    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
+
+    /* Update inode blocks count */
+    uint64_t ino_blocks =
+            ext4_inode_get_blocks_count(sb, inode_ref->inode);
+    ino_blocks -= count * (block_size / EXT4_INODE_BLOCK_SIZE);
+    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
+    inode_ref->dirty = true;
+
+    /* Update block group free blocks count */
+    uint32_t free_blocks =
+            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
+    free_blocks += count;
+    ext4_bg_set_free_blocks_count(bg_ref.block_group,
+        sb, free_blocks);
+    bg_ref.dirty = true;
+
+    /* Release block group reference */
+    rc = ext4_fs_put_block_group_ref(&bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    return EOK;
+}
+
+static uint32_t ext4_balloc_find_goal(struct ext4_inode_ref *inode_ref)
+{
+    uint32_t goal = 0;
+
+    struct ext4_sblock *sb = &inode_ref->fs->sb;
+
+    uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+    uint32_t inode_block_count = inode_size / block_size;
+
+    if (inode_size % block_size != 0)
+        inode_block_count++;
+
+    /* If inode has some blocks, get last block address + 1 */
+    if (inode_block_count > 0) {
+        int rc = ext4_fs_get_inode_data_block_index(inode_ref,
+                inode_block_count - 1, &goal);
+        if (rc != EOK)
+            return 0;
+
+        if (goal != 0) {
+            goal++;
+            return goal;
+        }
+
+        /* If goal == 0, sparse file -> continue */
+    }
+
+    /* Identify block group of inode */
+
+    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+    uint32_t block_group = (inode_ref->index - 1) / inodes_per_group;
+    block_size = ext4_sb_get_block_size(sb);
+
+    /* Load block group reference */
+    struct ext4_block_group_ref bg_ref;
+    int rc = ext4_fs_get_block_group_ref(inode_ref->fs,
+            block_group, &bg_ref);
+    if (rc != EOK)
+        return 0;
+
+    /* Compute indexes */
+    uint32_t block_group_count = ext4_block_group_cnt(sb);
+    uint32_t inode_table_first_block =
+            ext4_bg_get_inode_table_first_block(bg_ref.block_group, sb);
+    uint16_t inode_table_item_size = ext4_get16(sb, inode_size);
+    uint32_t inode_table_bytes;
+
+    /* Check for last block group */
+    if (block_group < block_group_count - 1) {
+        inode_table_bytes = inodes_per_group * inode_table_item_size;
+    } else {
+        /* Last block group could be smaller */
+        uint32_t inodes_count_total = ext4_get32(sb, inodes_count);
+
+        inode_table_bytes =
+                (inodes_count_total - ((block_group_count - 1) *
+                        inodes_per_group)) * inode_table_item_size;
+    }
+
+    uint32_t inode_table_blocks = inode_table_bytes / block_size;
+
+    if (inode_table_bytes % block_size)
+        inode_table_blocks++;
+
+    goal = inode_table_first_block + inode_table_blocks;
+
+    ext4_fs_put_block_group_ref(&bg_ref);
+
+    return goal;
+}
+
+
+int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref,
+    uint32_t *fblock)
+{
+    uint32_t allocated_block = 0;
+    uint32_t bitmap_block_addr;
+    uint32_t rel_block_idx = 0;
+
+    struct	ext4_block bitmap_block;
+
+    /* Find GOAL */
+    uint32_t goal = ext4_balloc_find_goal(inode_ref);
+    if (goal == 0) {
+        /* no goal found => partition is full */
+        return ENOSPC;
+    }
+
+    struct ext4_sblock *sb = &inode_ref->fs->sb;
+
+    /* Load block group number for goal and relative index */
+    uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal);
+    uint32_t index_in_group =
+            ext4_fs_baddr2_index_in_group(sb, goal);
+
+    /* Load block group reference */
+    struct ext4_block_group_ref bg_ref;
+    int rc = ext4_fs_get_block_group_ref(inode_ref->fs,
+            block_group, &bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    /* Compute indexes */
+    uint32_t first_in_group =
+            ext4_balloc_get_first_data_block_in_group(sb, &bg_ref);
+
+    uint32_t first_in_group_index =
+            ext4_fs_baddr2_index_in_group(sb, first_in_group);
+
+    if (index_in_group < first_in_group_index)
+        index_in_group = first_in_group_index;
+
+    /* Load block with bitmap */
+    bitmap_block_addr =
+            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
+
+    rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block,
+            bitmap_block_addr);
+    if (rc != EOK) {
+        ext4_fs_put_block_group_ref(&bg_ref);
+        return rc;
+    }
+
+    /* Check if goal is free */
+    if (ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group)) {
+        ext4_bmap_bit_set(bitmap_block.data, index_in_group);
+        bitmap_block.dirty = true;
+        rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+        if (rc != EOK) {
+            ext4_fs_put_block_group_ref(&bg_ref);
+            return rc;
+        }
+
+        allocated_block =
+                ext4_fs_index_in_group2_baddr(sb, index_in_group,
+                        block_group);
+
+        goto success;
+    }
+
+    uint32_t blocks_in_group =
+            ext4_blocks_in_group_cnt(sb, block_group);
+
+    uint32_t end_idx = (index_in_group + 63) & ~63;
+    if (end_idx > blocks_in_group)
+        end_idx = blocks_in_group;
+
+    /* Try to find free block near to goal */
+    uint32_t tmp_idx;
+    for (tmp_idx = index_in_group + 1; tmp_idx < end_idx;
+            ++tmp_idx) {
+        if (ext4_bmap_is_bit_clr(bitmap_block.data, tmp_idx)) {
+            ext4_bmap_bit_set(bitmap_block.data, tmp_idx);
+
+            bitmap_block.dirty = true;
+            rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+            if (rc != EOK)
+                return rc;
+
+            allocated_block =
+                    ext4_fs_index_in_group2_baddr(sb, tmp_idx,
+                            block_group);
+
+            goto success;
+        }
+    }
+
+
+
+    /* Find free bit in bitmap */
+    rc = ext4_bmap_bit_find_clr(bitmap_block.data,
+            index_in_group, blocks_in_group, &rel_block_idx);
+    if (rc == EOK) {
+        ext4_bmap_bit_set(bitmap_block.data, rel_block_idx);
+        bitmap_block.dirty = true;
+        rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+        if (rc != EOK)
+            return rc;
+
+        allocated_block =
+                ext4_fs_index_in_group2_baddr(sb, rel_block_idx,
+                        block_group);
+
+        goto success;
+    }
+
+    /* No free block found yet */
+    ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+    ext4_fs_put_block_group_ref(&bg_ref);
+
+    /* Try other block groups */
+    uint32_t block_group_count = ext4_block_group_cnt(sb);
+
+    uint32_t bgid = (block_group + 1) % block_group_count;
+    uint32_t count = block_group_count;
+
+    while (count > 0) {
+        rc = ext4_fs_get_block_group_ref(inode_ref->fs, bgid,
+                &bg_ref);
+        if (rc != EOK)
+            return rc;
+
+        /* Load block with bitmap */
+        bitmap_block_addr =
+                ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
+
+        rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block,
+                bitmap_block_addr);
+
+        if (rc != EOK) {
+            ext4_fs_put_block_group_ref(&bg_ref);
+            return rc;
+        }
+
+        /* Compute indexes */
+        first_in_group =
+                ext4_balloc_get_first_data_block_in_group(sb, &bg_ref);
+        index_in_group =
+                ext4_fs_baddr2_index_in_group(sb, first_in_group);
+        blocks_in_group = ext4_blocks_in_group_cnt(sb, bgid);
+
+        first_in_group_index =
+                ext4_fs_baddr2_index_in_group(sb, first_in_group);
+
+        if (index_in_group < first_in_group_index)
+            index_in_group = first_in_group_index;
+
+
+        rc = ext4_bmap_bit_find_clr(bitmap_block.data,
+                index_in_group, blocks_in_group, &rel_block_idx);
+
+        if (rc == EOK) {
+
+            ext4_bmap_bit_set(bitmap_block.data, rel_block_idx);
+
+            bitmap_block.dirty = true;
+            rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+            if (rc != EOK)
+                return rc;
+
+            allocated_block =
+                    ext4_fs_index_in_group2_baddr(sb, rel_block_idx,
+                            bgid);
+
+            goto success;
+        }
+
+        ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+        ext4_fs_put_block_group_ref(&bg_ref);
+
+        /* Goto next group */
+        bgid = (bgid + 1) % block_group_count;
+        count--;
+    }
+
+    return ENOSPC;
+
+    success:
+    /* Empty command - because of syntax */
+    ;
+
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+
+    /* Update superblock free blocks count */
+    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);
+    sb_free_blocks--;
+    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
+
+    /* Update inode blocks (different block size!) count */
+    uint64_t ino_blocks =
+            ext4_inode_get_blocks_count(sb, inode_ref->inode);
+    ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
+    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
+    inode_ref->dirty = true;
+
+    /* Update block group free blocks count */
+    uint32_t bg_free_blocks =
+            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
+    bg_free_blocks--;
+    ext4_bg_set_free_blocks_count(bg_ref.block_group, sb,
+        bg_free_blocks);
+
+    bg_ref.dirty = true;
+
+    ext4_fs_put_block_group_ref(&bg_ref);
+
+    *fblock = allocated_block;
+    return EOK;
+}
+
+int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,
+    uint32_t baddr, bool *free)
+{
+    int rc = EOK;
+
+    struct ext4_fs *fs = inode_ref->fs;
+    struct ext4_sblock *sb = &fs->sb;
+
+    /* Compute indexes */
+    uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr);
+    uint32_t index_in_group =
+            ext4_fs_baddr2_index_in_group(sb, baddr);
+
+    /* Load block group reference */
+    struct ext4_block_group_ref bg_ref;
+    rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    /* Load block with bitmap */
+    uint32_t bitmap_block_addr =
+            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
+
+
+    struct	ext4_block bitmap_block;
+
+    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Check if block is free */
+    *free = ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group);
+
+    /* Allocate block if possible */
+    if (*free) {
+        ext4_bmap_bit_set(bitmap_block.data, index_in_group);
+        bitmap_block.dirty = true;
+    }
+
+    /* Release block with bitmap */
+    rc = ext4_block_set(fs->bdev, &bitmap_block);
+    if (rc != EOK) {
+        /* Error in saving bitmap */
+        ext4_fs_put_block_group_ref(&bg_ref);
+        return rc;
+    }
+
+    /* If block is not free, return */
+    if (!(*free))
+        goto terminate;
+
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+
+    /* Update superblock free blocks count */
+    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);
+    sb_free_blocks--;
+    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
+
+    /* Update inode blocks count */
+    uint64_t ino_blocks =
+            ext4_inode_get_blocks_count(sb, inode_ref->inode);
+    ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
+    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
+    inode_ref->dirty = true;
+
+    /* Update block group free blocks count */
+    uint32_t free_blocks =
+            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
+    free_blocks--;
+    ext4_bg_set_free_blocks_count(bg_ref.block_group,
+        sb, free_blocks);
+
+    bg_ref.dirty = true;
+
+    terminate:
+    return ext4_fs_put_block_group_ref(&bg_ref);
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_balloc.h
@@ -1,0 +1,93 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_balloc.h
+ * @brief Physical block allocator.
+ */
+
+#ifndef EXT4_BALLOC_H_
+#define EXT4_BALLOC_H_
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/**@brief	Get first datablock in block group
+ * @param	s superblock descriptor
+ * @param	bg_ref block group reference
+ * @return	block id of the first datablock in block group*/
+uint32_t ext4_balloc_get_first_data_block_in_group(struct ext4_sblock *s,
+         struct ext4_block_group_ref * bg_ref);
+
+/**@brief	Free block from inode.
+ * @param	inode_ref inode reference
+ * @param	baddr block address
+ * @return 	standard error code*/
+int 	ext4_balloc_free_block(struct ext4_inode_ref *inode_ref,
+        uint32_t baddr);
+
+/**@brief	Free blocks from inode.
+ * @param	inode_ref inode reference
+ * @param	baddr block address
+ * @return 	standard error code*/
+int 	ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref,
+        uint32_t first, uint32_t count);
+
+/**@brief	Allocate block procedure.
+ * @param	inode_ref inode reference
+ * @param	baddr allocated block address
+ * @return 	standard error code*/
+int 	ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref,
+        uint32_t *baddr);
+
+/**@brief	Try allocate selected block.
+ * @param	inode_ref inode reference
+ * @param	baddr block address to allocate
+ * @param	free if baddr is not allocated
+ * @return 	standard error code*/
+int 	ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,
+        uint32_t baddr, bool *free);
+
+#endif /* EXT4_BALLOC_H_ */
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_bcache.c
@@ -1,0 +1,276 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_bcache.c
+ * @brief Block cache allocator.
+ */
+
+#include <ext4_config.h>
+#include <ext4_bcache.h>
+#include <ext4_debug.h>
+#include <ext4_errno.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+
+int	ext4_bcache_init_dynamic(struct	ext4_bcache *bc, uint32_t cnt,
+    uint32_t itemsize)
+{
+    ext4_assert(bc && cnt && itemsize);
+
+    bc->lru_ctr= 0;
+
+    bc->refctr	 	= 0;
+    bc->lru_id 		= 0;
+    bc->free_delay  = 0;
+    bc->lba	  	 	= 0;
+    bc->data	 	= 0;
+
+    bc->refctr   = malloc(cnt * sizeof(uint32_t));
+    if(!bc->refctr)
+        goto error;
+
+    bc->lru_id = malloc(cnt * sizeof(uint32_t));
+    if(!bc->lru_id)
+        goto error;
+
+    bc->free_delay = malloc(cnt * sizeof(uint8_t));
+    if(!bc->free_delay)
+        goto error;
+
+    bc->lba 	 = malloc(cnt * sizeof(uint64_t));
+    if(!bc->lba)
+        goto error;
+
+    bc->data	 = malloc(cnt * itemsize);
+    if(!bc->data)
+        goto error;
+
+    memset(bc->refctr, 0, cnt * sizeof(uint32_t));
+    memset(bc->lru_id, 0, cnt * sizeof(uint32_t));
+    memset(bc->free_delay, 0, cnt * sizeof(uint8_t));
+    memset(bc->lba, 0, cnt * sizeof(uint64_t));
+
+    bc->cnt      = cnt;
+    bc->itemsize = itemsize;
+    bc->ref_blocks = 0;
+    bc->max_ref_blocks = 0;
+
+    return EOK;
+
+    error:
+
+    if(bc->refctr)
+        free(bc->refctr);
+
+    if(bc->lru_id)
+        free(bc->lru_id);
+
+    if(bc->free_delay)
+        free(bc->free_delay);
+
+    if(bc->lba)
+        free(bc->lba);
+
+    if(bc->data)
+        free(bc->data);
+
+    return ENOMEM;
+}
+
+int ext4_bcache_fini_dynamic(struct	ext4_bcache *bc)
+{
+    if(bc->refctr)
+        free(bc->refctr);
+
+    if(bc->lru_id)
+        free(bc->lru_id);
+
+    if(bc->free_delay)
+        free(bc->free_delay);
+
+    if(bc->lba)
+        free(bc->lba);
+
+    if(bc->data)
+        free(bc->data);
+
+    bc->lru_ctr= 0;
+
+    bc->refctr	 	= 0;
+    bc->lru_id 		= 0;
+    bc->free_delay  = 0;
+    bc->lba	  	 	= 0;
+    bc->data	 	= 0;
+
+    return EOK;
+}
+
+
+int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,
+    bool *is_new)
+{
+    uint32_t i;
+    ext4_assert(bc && b && is_new);
+
+    /*Check if valid.*/
+    ext4_assert(b->lb_id);
+    if(!b->lb_id){
+        ext4_assert(b->lb_id);
+    }
+
+    uint32_t cache_id = bc->cnt;
+    uint32_t alloc_id;
+
+    *is_new = false;
+
+    /*Find in free blocks (Last Recently Used).*/
+    for (i = 0; i < bc->cnt; ++i) {
+
+        /*Check if block is already in cache*/
+        if(b->lb_id == bc->lba[i]){
+
+            if(!bc->refctr[i] && !bc->free_delay[i])
+                bc->ref_blocks++;
+
+            /*Update reference counter*/
+            bc->refctr[i]++;
+
+            /*Update usage marker*/
+            bc->lru_id[i] = ++bc->lru_ctr;
+
+            /*Set valid cache data and id*/
+            b->data = bc->data + i * bc->itemsize;
+            b->cache_id = i;
+
+            return EOK;
+        }
+
+        /*Best fit calculations.*/
+        if(bc->refctr[i])
+            continue;
+
+        if(bc->free_delay[i])
+            continue;
+
+        /*Block is unreferenced, but it may exist block with
+         * lower usage marker*/
+
+        /*First find.*/
+        if(cache_id == bc->cnt){
+            cache_id = i;
+            alloc_id = bc->lru_id[i];
+            continue;
+        }
+
+        /*Next find*/
+        if(alloc_id <= bc->lru_id[i])
+            continue;
+
+        /*This block has lower alloc id marker*/
+        cache_id = i;
+        alloc_id = bc->lru_id[i];
+    }
+
+
+    if(cache_id != bc->cnt){
+        /*There was unreferenced block*/
+        bc->lba[cache_id] 	   = b->lb_id;
+        bc->refctr[cache_id]   = 1;
+        bc->lru_id[cache_id] = ++bc->lru_ctr;
+
+        /*Set valid cache data and id*/
+        b->data = bc->data + cache_id * bc->itemsize;
+        b->cache_id = cache_id;
+
+        /*Statistics*/
+        bc->ref_blocks++;
+        if(bc->ref_blocks > bc->max_ref_blocks)
+            bc->max_ref_blocks = bc->ref_blocks;
+
+
+        /*Block needs to be read.*/
+        *is_new = true;
+
+        return EOK;
+    }
+
+    ext4_dprintf(EXT4_DEBUG_BCACHE,
+        "ext4_bcache_alloc: FAIL, unable to alloc block cache!\n");
+    return ENOMEM;
+}
+
+int ext4_bcache_free (struct ext4_bcache *bc, struct ext4_block *b,
+    uint8_t free_delay)
+{
+    ext4_assert(bc && b);
+
+    /*Check if valid.*/
+    ext4_assert(b->lb_id);
+
+    /*Block should be in cache.*/
+    ext4_assert(b->cache_id < bc->cnt);
+
+    /*Check if someone don't try free unreferenced block cache.*/
+    ext4_assert(bc->refctr[b->cache_id]);
+
+    /*Just decrease reference counter*/
+    if(bc->refctr[b->cache_id])
+        bc->refctr[b->cache_id]--;
+
+    if(free_delay)
+        bc->free_delay[b->cache_id] = free_delay;
+
+    /*Update statistics*/
+    if(!bc->refctr[b->cache_id] && !bc->free_delay[b->cache_id])
+        bc->ref_blocks--;
+
+    b->lb_id    = 0;
+    b->data     = 0;
+    b->cache_id = 0;
+
+    return EOK;
+}
+
+
+
+bool ext4_bcache_is_full(struct ext4_bcache *bc)
+{
+    return (bc->cnt == bc->ref_blocks);
+}
+
+/**
+ * @}
+ */
+
+
--- /dev/null
+++ b/lwext4/ext4_bcache.h
@@ -1,0 +1,155 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_bcache.h
+ * @brief Block cache allocator.
+ */
+
+#ifndef EXT4_BCACHE_H_
+#define EXT4_BCACHE_H_
+
+#include <ext4_config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**@brief	Single block descriptor.*/
+struct	ext4_block {
+    /**@brief	Dirty flag.*/
+    bool		dirty;
+
+    /**@brief	Logical block ID*/
+    uint64_t	lb_id;
+
+    /**@brief   Cache id*/
+    uint32_t    cache_id;
+
+    /**@brief	Data buffer.*/
+    uint8_t		*data;
+};
+
+
+/**@brief	Block cache descriptor.*/
+struct	ext4_bcache {
+
+    /**@brief	Item count in block cache*/
+    uint32_t	cnt;
+
+    /**@brief	Item size in block cache*/
+    uint32_t	itemsize;
+
+    /**@brief	Last recently used counter.*/
+    uint32_t	lru_ctr;
+
+    /**@brief	Reference count table (cnt).*/
+    uint32_t	*refctr;
+
+    /**@brief	Last recently used ID table (cnt)*/
+    uint32_t 	*lru_id;
+
+    /**@brief	Free delay mode table (cnt)*/
+    uint8_t 	*free_delay;
+
+    /**@brief	Logical block table (cnt).*/
+    uint64_t	*lba;
+
+    /**@brief	Cache data buffers (cnt * itemsize)*/
+    uint8_t		*data;
+
+    /**@brief	Currently referenced datablocks*/
+    uint32_t	ref_blocks;
+
+    /**@brief	Maximum referenced datablocks*/
+    uint32_t	max_ref_blocks;
+
+};
+
+/**@brief	Static initializer of block cache structure.*/
+#define EXT4_BCACHE_STATIC_INSTANCE(__name, __cnt, __itemsize)      \
+        static uint32_t	__name##_refctr[(__cnt)];                   \
+        static uint32_t	__name##_lru_id[(__cnt)];                   \
+        static uint8_t		__name##_free_delay[(__cnt)];           \
+        static uint64_t	__name##_lba[(__cnt)];                      \
+        static uint8_t 	__name##_data[(__cnt) * (__itemsize)];      \
+        static struct ext4_bcache	__name = {                      \
+                .cnt 	   = __cnt,                                 \
+                .itemsize  = __itemsize,                            \
+                .lru_ctr   = 0,                                     \
+                .refctr	   = __name##_refctr,                       \
+                .lru_id    = __name##_lru_id,                       \
+                .lba	   = __name##_lba,                          \
+                .free_delay= __name##_free_delay,                   \
+                .data	   = __name##_data,                         \
+        }
+
+
+/**@brief	Dynamic initialization of block cache.
+ * @param	bc block cache descriptor
+ * @param	cnt items count in block cache
+ * @param	itemsize single item size (in bytes)
+ * @return	standard error code*/
+int	ext4_bcache_init_dynamic(struct	ext4_bcache *bc, uint32_t cnt,
+    uint32_t itemsize);
+
+/**@brief	Dynamic de-initialization of block cache.
+ * @param	bc block cache descriptor
+ * @return	standard error code*/
+int ext4_bcache_fini_dynamic(struct	ext4_bcache *bc);
+
+/**@brief	Allocate block from block cache memory.
+ *          Unreferenced block allocation is based on LRU
+ *          (Last Recently Used) algorithm.
+ * @param 	bc	block cache descriptor
+ * @param	b block to alloc
+ * @param	is_new block is new (needs to be read)
+ * @return  standard error code*/
+int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,
+    bool *is_new);
+
+/**@brief	Free block from cache memory (decrement reference counter).
+ * @param 	bc	block cache descriptor
+ * @param	b block to free
+ * @return  standard error code*/
+int ext4_bcache_free (struct ext4_bcache *bc, struct ext4_block *b,
+    uint8_t free_delay);
+
+
+/**@brief	Return a full status of block cache.
+ * @param 	bc	block cache descriptor
+ * @return	full status*/
+bool ext4_bcache_is_full(struct ext4_bcache *bc);
+
+#endif /* EXT4_BCACHE_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_bitmap.c
@@ -1,0 +1,173 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_bitmap.c
+ * @brief Block/inode bitmap allocator.
+ */
+
+#include <ext4_config.h>
+#include <ext4_bitmap.h>
+
+#include <ext4_errno.h>
+
+
+void ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt)
+{
+    uint32_t i;
+
+    i = sbit;
+
+    while(i & 7){
+
+        if(!bcnt)
+            return;
+
+        ext4_bmap_bit_clr(bmap, i);
+
+        bcnt--;
+        i++;
+    }
+
+    sbit  = i;
+    bmap += (sbit >> 3);
+
+
+
+    while(bcnt >= 32){
+        *(uint32_t *)bmap = 0;
+
+        bmap += 4;
+        bcnt -= 32;
+        sbit += 32;
+    }
+
+    while(bcnt >= 16){
+        *(uint16_t *)bmap = 0;
+
+        bmap += 2;
+        bcnt -= 16;
+        sbit += 16;
+    }
+
+    while(bcnt >= 8){
+        *bmap = 0;
+
+        bmap += 1;
+        bcnt -= 8;
+        sbit += 8;
+    }
+
+    for (i = 0; i < bcnt; ++i) {
+        ext4_bmap_bit_clr(bmap, i);
+    }
+}
+
+
+
+int ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit,
+    uint32_t *bit_id)
+{
+    uint32_t i;
+    uint32_t bcnt = ebit - sbit;
+
+    i = sbit;
+
+    while(i & 7){
+
+        if(!bcnt)
+            return ENOSPC;
+
+        if(ext4_bmap_is_bit_clr(bmap, i)){
+            *bit_id = sbit;
+            return EOK;
+        }
+
+        i++;
+        bcnt--;
+    }
+
+    sbit  = i;
+    bmap += (sbit >> 3);
+
+
+    while(bcnt >= 32){
+        if(*(uint32_t *)bmap != 0xFFFFFFFF)
+            goto finish_it;
+
+
+        bmap += 4;
+        bcnt -= 32;
+        sbit += 32;
+    }
+
+    while(bcnt >= 16){
+        if(*(uint16_t *)bmap != 0xFFFF)
+            goto finish_it;
+
+
+        bmap += 2;
+        bcnt -= 16;
+        sbit += 16;
+    }
+
+    finish_it:
+    while(bcnt >= 8){
+        if(*bmap != 0xFF){
+            for (i = 0; i < 8; ++i) {
+                if(ext4_bmap_is_bit_clr(bmap, i)){
+                    *bit_id = sbit + i;
+                    return EOK;
+                }
+            }
+        }
+
+        bmap += 1;
+        bcnt -= 8;
+        sbit += 8;
+    }
+
+    for (i = 0; i < bcnt; ++i) {
+        if(ext4_bmap_is_bit_clr(bmap, i)){
+            *bit_id = sbit + i;
+            return EOK;
+        }
+    }
+
+
+    return ENOSPC;
+}
+
+/**
+ * @}
+ */
+
+
--- /dev/null
+++ b/lwext4/ext4_bitmap.h
@@ -1,0 +1,98 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_bitmap.h
+ * @brief Block/inode bitmap allocator.
+ */
+
+
+#ifndef EXT4_BITMAP_H_
+#define EXT4_BITMAP_H_
+
+#include <ext4_config.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/**@brief	Set bitmap bit.
+ * @param	bmap bitmap
+ * @param	bit	 bit to set*/
+static inline void ext4_bmap_bit_set(uint8_t *bmap, uint32_t bit)
+{
+    *(bmap + (bit >> 3)) |= (1 << (bit & 7));
+}
+
+/**@brief	Clear bitmap bit.
+ * @param	bmap bitmap buffer
+ * @param	bit	 bit to clear*/
+static inline void ext4_bmap_bit_clr(uint8_t *bmap, uint32_t bit)
+{
+    *(bmap + (bit >> 3)) &= ~(1 << (bit & 7));
+}
+
+
+/**@brief	Check if the bitmap bit is set.
+ * @param	bmap bitmap buffer
+ * @param	bit	 bit to check*/
+static inline bool ext4_bmap_is_bit_set(uint8_t *bmap, uint32_t bit)
+{
+    return (*(bmap + (bit >> 3)) & (1 << (bit & 7)));
+}
+
+/**@brief	Check if the bitmap bit is clear.
+ * @param	bmap bitmap buffer
+ * @param	bit	 bit to check*/
+static inline bool ext4_bmap_is_bit_clr(uint8_t *bmap, uint32_t bit)
+{
+    return !ext4_bmap_is_bit_set(bmap, bit);
+}
+
+/**@brief	Free range of bits in bitmap.
+ * @param	bmap bitmap buffer
+ * @param	sbit start bit
+ * @param	bcnt bit count*/
+void ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt);
+
+/**@brief	Find first clear bit in bitmap.
+ * @param	sbit start bit of search
+ * @param	ebit end bit of search
+ * @param	bit_id output parameter (first free bit)
+ * @return	standard error code*/
+int ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit,
+    uint32_t *bit_id);
+
+
+#endif /* EXT4_BITMAP_H_ */
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_block_group.c
@@ -1,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_block_group.c
+ * @brief Block group function set.
+ */
+
+#include <ext4_config.h>
+#include <ext4_block_group.h>
+
+
+
+uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len)
+{
+    // TODO
+    return 0;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_block_group.h
@@ -1,0 +1,199 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_block_group.h
+ * @brief Block group function set.
+ */
+
+#ifndef EXT4_BLOCK_GROUP_H_
+#define EXT4_BLOCK_GROUP_H_
+
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <ext4_super.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg,
+    struct ext4_sblock *s)
+{
+    uint64_t v = to_le32(bg->block_bitmap_lo);
+
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint64_t) to_le32(bg->block_bitmap_hi) << 32;
+
+    return v;
+}
+
+static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg,
+    struct ext4_sblock *s)
+{
+
+    uint64_t v = to_le32(bg->inode_bitmap_lo);
+
+    if (ext4_sb_get_desc_size(s)> EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint64_t) to_le32(bg->inode_bitmap_hi) << 32;
+
+    return v;
+}
+
+static inline uint64_t ext4_bg_get_inode_table_first_block(
+    struct ext4_bgroup *bg, struct ext4_sblock *s)
+{
+    uint64_t v = to_le32(bg->inode_table_first_block_lo);
+
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint64_t) to_le32(bg->inode_table_first_block_hi) << 32;
+
+    return v;
+}
+
+static inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg,
+    struct ext4_sblock *s)
+{
+    uint32_t v = to_le16(bg->free_blocks_count_lo);
+
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint32_t) to_le16(bg->free_blocks_count_hi) << 16;
+
+    return v;
+}
+
+static inline void 	 ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg,
+    struct ext4_sblock *s, uint32_t cnt)
+{
+    bg->free_blocks_count_lo = to_le16((cnt << 16) >> 16);
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        bg->free_blocks_count_hi = to_le16(cnt >> 16);
+}
+
+static inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg,
+    struct ext4_sblock *s)
+{
+    uint32_t v = to_le16(bg->free_inodes_count_lo);
+
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint32_t) to_le16(bg->free_inodes_count_hi) << 16;
+
+    return v;
+}
+
+static inline void 	 ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg,
+    struct ext4_sblock *s, uint32_t cnt)
+{
+    bg->free_inodes_count_lo = to_le16((cnt << 16) >> 16);
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        bg->free_inodes_count_hi = to_le16(cnt >> 16);
+}
+
+
+static inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg,
+    struct ext4_sblock *s)
+{
+    uint32_t v = to_le16(bg->used_dirs_count_lo);
+
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint32_t) to_le16(bg->used_dirs_count_hi) << 16;
+
+    return v;
+}
+
+static inline void 	 ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg,
+    struct ext4_sblock *s, uint32_t cnt)
+{
+    bg->used_dirs_count_lo = to_le16((cnt << 16) >> 16);
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        bg->used_dirs_count_hi = to_le16(cnt >> 16);
+}
+
+
+static inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg,
+    struct ext4_sblock *s)
+{
+
+    uint32_t v = to_le16(bg->itable_unused_lo);
+
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        v |= (uint32_t) to_le16(bg->itable_unused_hi) << 16;
+
+    return v;
+}
+
+static inline void 	 ext4_bg_set_itable_unused(struct ext4_bgroup *bg,
+    struct ext4_sblock *s, uint32_t cnt)
+{
+    bg->itable_unused_lo = to_le16((cnt << 16) >> 16);
+    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        bg->itable_unused_hi = to_le16(cnt >> 16);
+}
+
+
+static inline void 	 ext4_bg_set_checksum(struct ext4_bgroup *bg,
+    uint16_t crc)
+{
+    bg->checksum = to_le16(crc);
+}
+
+static inline bool 	 ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f)
+{
+    return to_le16(bg->flags) & f;
+}
+
+static inline void 	 ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f)
+{
+    uint16_t flags = to_le16(bg->flags);
+    flags |= f;
+    bg->flags = to_le16(flags);
+}
+
+static inline void 	 ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f)
+{
+    uint16_t flags = to_le16(bg->flags);
+    flags &= ~f;
+    bg->flags = to_le16(flags);
+}
+
+
+uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len);
+
+#endif /* EXT4_BLOCK_GROUP_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_blockdev.c
@@ -1,0 +1,448 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_blockdev.c
+ * @brief Block device module.
+ */
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+#include <ext4_errno.h>
+#include <ext4_debug.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+
+
+int	ext4_block_init(struct	ext4_blockdev *bdev)
+{
+    int rc;
+    ext4_assert(bdev);
+
+    ext4_assert(bdev->open && bdev->close && bdev->bread  && bdev->bwrite);
+
+    /*Low level block init*/
+    rc = bdev->open(bdev);
+    if(EOK != rc)
+        return rc;
+
+    bdev->flags |= EXT4_BDEV_INITIALIZED;
+
+    return	EOK;
+}
+
+int ext4_block_bind_bcache(struct ext4_blockdev *bdev, struct ext4_bcache *bc)
+{
+    ext4_assert(bdev && bc);
+    bdev->bc = bc;
+    return EOK;
+}
+
+void ext4_block_set_lb_size(struct	ext4_blockdev *bdev, uint64_t	lb_bsize)
+{
+    /*Logical block size has to be multiply of physical */
+    ext4_assert(!(lb_bsize % bdev->ph_bsize));
+
+    bdev->lg_bsize = lb_bsize;
+    bdev->lg_bcnt = (bdev->ph_bcnt * bdev->ph_bsize) / lb_bsize;
+
+}
+
+int ext4_block_fini(struct	ext4_blockdev *bdev)
+{
+    ext4_assert(bdev);
+
+    bdev->flags &= ~(EXT4_BDEV_INITIALIZED);
+
+    /*Low level block fini*/
+    return bdev->close(bdev);
+}
+
+
+int ext4_block_get(struct	ext4_blockdev *bdev, struct	ext4_block *b,
+    uint64_t lba)
+{
+    uint64_t pba;
+    uint32_t pb_cnt;
+    bool	 is_new;
+    int 	 r;
+    ext4_assert(bdev && b);
+
+    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
+        return EIO;
+
+    if(!(lba < bdev->lg_bcnt))
+        return ERANGE;
+
+    b->dirty = 0;
+    b->lb_id = lba;
+
+    r = ext4_bcache_alloc(bdev->bc, b, &is_new);
+    if(r != EOK)
+        return r;
+
+
+    if(!is_new){
+        /*Block is in cache. Read from physical device is not required*/
+        return EOK;
+    }
+
+    if(!b->data)
+        return ENOMEM;
+
+    pba 	= (lba * bdev->lg_bsize) / bdev->ph_bsize;
+    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
+
+
+    r = bdev->bread(bdev, b->data, pba, pb_cnt);
+
+    if(r != EOK){
+        ext4_bcache_free(bdev->bc, b, 0);
+        b->lb_id = 0;
+        return r;
+    }
+
+    bdev->bread_ctr++;
+
+    return EOK;
+}
+
+int ext4_block_set(struct	ext4_blockdev *bdev, struct	ext4_block *b)
+{
+    uint64_t pba;
+    uint32_t pb_cnt;
+    uint32_t i;
+    int r;
+
+    ext4_assert(bdev && b);
+
+    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
+        return EIO;
+
+    /*Doesn,t need to write.*/
+    if(b->dirty == false){
+        ext4_bcache_free(bdev->bc, b, 0);
+        return EOK;
+    }
+
+    /*Free cache delay mode*/
+    if(bdev->cache_flush_delay){
+
+        /*Free cahe block and mark as free delayed*/
+        ext4_bcache_free(bdev->bc, b, bdev->cache_flush_delay);
+
+        /*If cache is full we have to flush it anyway :(*/
+        if(ext4_bcache_is_full(bdev->bc)){
+            for (i = 0; i < bdev->bc->cnt; ++i) {
+                /*Check if buffer free was delayed.*/
+                if(!bdev->bc->free_delay[i])
+                    continue;
+
+                /*Check reference counter.*/
+                if(bdev->bc->refctr[i])
+                    continue;
+
+                /*Buffer free was delayed and have no reference. Flush it.*/
+                r = ext4_block_set_direct(bdev,
+                        bdev->bc->data + bdev->bc->itemsize * i,
+                        bdev->bc->lba[i]);
+                if(r != EOK)
+                    return r;
+
+                /*No delayed anymore*/
+                bdev->bc->free_delay[i] = 0;
+
+                /*Reduce refered block count*/
+                bdev->bc->ref_blocks--;
+            }
+        }
+
+        return EOK;
+    }
+
+    pba 	= (b->lb_id * bdev->lg_bsize) / bdev->ph_bsize;
+    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
+
+
+    r = bdev->bwrite(bdev, b->data, pba, pb_cnt);
+
+    if(r != EOK){
+        b->dirty = false;
+        ext4_bcache_free(bdev->bc, b, 0);
+        return r;
+    }
+
+    bdev->bwrite_ctr++;
+    b->dirty = false;
+    ext4_bcache_free(bdev->bc, b, 0);
+    return EOK;
+}
+
+int ext4_block_get_direct(struct	ext4_blockdev *bdev, void *buf,
+    uint64_t lba)
+{
+    uint64_t pba;
+    uint32_t pb_cnt;
+
+    ext4_assert(bdev && buf);
+
+    pba 	= (lba * bdev->lg_bsize) / bdev->ph_bsize;
+    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
+
+    bdev->bread_ctr++;
+
+    return bdev->bread(bdev, buf, pba, pb_cnt);
+}
+
+
+
+int ext4_block_set_direct(struct	ext4_blockdev *bdev, const void *buf,
+    uint64_t lba)
+{
+    uint64_t pba;
+    uint32_t pb_cnt;
+
+    ext4_assert(bdev && buf);
+
+    pba 	= (lba * bdev->lg_bsize) / bdev->ph_bsize;
+    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
+
+    bdev->bwrite_ctr++;
+
+    return bdev->bwrite(bdev, buf, pba, pb_cnt);
+}
+
+
+int	ext4_block_writebytes(struct	ext4_blockdev *bdev, uint64_t off,
+    const void *buf, uint32_t len)
+{
+    uint64_t block_idx;
+    uint64_t block_end;
+
+    uint32_t blen;
+
+    uint32_t unalg;
+    int		 r = EOK;
+
+    const uint8_t	*p = (void *)buf;
+
+    ext4_assert(bdev && buf);
+
+    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
+        return EIO;
+
+
+    block_idx =  off / bdev->ph_bsize;
+    block_end   =  block_idx + len / bdev->ph_bsize;
+
+    if(!(block_end < bdev->ph_bcnt))
+        return EINVAL;				/*Ups. Out of range operation*/
+
+
+    /*OK lets deal with the first possible unaligned block*/
+    unalg = (off & (bdev->ph_bsize - 1));
+    if(unalg){
+
+        uint32_t wlen = (bdev->ph_bsize - unalg) > len ?
+                len : (bdev->ph_bsize - unalg);
+
+        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
+
+        if(r != EOK)
+            return r;
+
+        memcpy(bdev->ph_bbuf + unalg, p, wlen);
+
+        r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1);
+
+        if(r != EOK)
+            return r;
+
+        p   += wlen;
+        len -= wlen;
+        block_idx++;
+    }
+
+
+    /*Aligned data*/
+    blen = len / bdev->ph_bsize;
+
+    r = bdev->bwrite(bdev, p, block_idx, blen);
+
+    if(r != EOK)
+        return r;
+
+    p 	+= bdev->ph_bsize * blen;
+    len -= bdev->ph_bsize * blen;
+
+    block_idx += blen;
+
+
+    /*Rest of the data*/
+    if(len){
+
+        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
+
+        if(r != EOK)
+            return r;
+
+        memcpy(bdev->ph_bbuf, p, len);
+
+        r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1);
+
+        if(r != EOK)
+            return r;
+    }
+
+    return r;
+}
+
+
+
+
+int ext4_block_readbytes(struct	ext4_blockdev *bdev, uint64_t off, void *buf,
+    uint32_t len)
+{
+
+    uint64_t block_idx;
+    uint64_t block_end;
+    uint32_t blen;
+
+    uint32_t unalg;
+    int		 r = EOK;
+
+    uint8_t	*p = (void *)buf;
+
+    ext4_assert(bdev && buf);
+
+    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
+        return EIO;
+
+
+    block_idx =  off / bdev->ph_bsize;
+    block_end   =  block_idx + len / bdev->ph_bsize;
+
+    if(!(block_end < bdev->ph_bcnt))
+        return EINVAL;				/*Ups. Out of range operation*/
+
+
+    /*OK lets deal with the first possible unaligned block*/
+    unalg = (off & (bdev->ph_bsize - 1));
+    if(unalg){
+
+        uint32_t rlen = (bdev->ph_bsize - unalg) > len ?
+                len : (bdev->ph_bsize - unalg);
+
+        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
+
+        if(r != EOK)
+            return r;
+
+        memcpy(p, bdev->ph_bbuf + unalg, rlen);
+
+        p   += rlen;
+        len -= rlen;
+        block_idx++;
+    }
+
+
+    /*Aligned data*/
+    blen = len / bdev->ph_bsize;
+
+    r = bdev->bread(bdev, p, block_idx, blen);
+
+    if(r != EOK)
+        return r;
+
+    p 	+= bdev->ph_bsize * blen;
+    len -= bdev->ph_bsize * blen;
+
+    block_idx += blen;
+
+
+    /*Rest of the data*/
+    if(len){
+
+        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
+
+        if(r != EOK)
+            return r;
+
+        memcpy(p, bdev->ph_bbuf, len);
+
+    }
+
+    return r;
+}
+
+int 	ext4_block_delay_cache_flush(struct	ext4_blockdev *bdev,
+    uint8_t on_off)
+{
+    int r;
+    uint32_t i;
+    bdev->cache_flush_delay = on_off;
+
+    /*Flush all delayed cache blocks*/
+    if(!on_off){
+        for (i = 0; i < bdev->bc->cnt; ++i) {
+
+            /*Check if buffer free was delayed.*/
+            if(!bdev->bc->free_delay[i])
+                continue;
+
+            /*Check reference counter.*/
+            if(bdev->bc->refctr[i])
+                continue;
+
+            /*Buffer free was delayed and have no reference. Flush it.*/
+            r = ext4_block_set_direct(bdev,
+                    bdev->bc->data + bdev->bc->itemsize * i,
+                    bdev->bc->lba[i]);
+            if(r != EOK)
+                return r;
+
+            /*No delayed anymore*/
+            bdev->bc->free_delay[i] = 0;
+
+            /*Reduce refered block count*/
+            bdev->bc->ref_blocks--;
+        }
+    }
+
+    return EOK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_blockdev.h
@@ -1,0 +1,211 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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.
+ */
+#ifndef EXT4_BLOCKDEV_H_
+#define EXT4_BLOCKDEV_H_
+
+/** @addtogroup lwext4
+ * @{
+ */
+/**
+ * @file  ext4_blockdev.h
+ * @brief Block device module.
+ */
+
+#include <ext4_config.h>
+#include <ext4_bcache.h>
+#include <ext4_debug.h>
+
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/**@brief	Initialization status flag*/
+#define EXT4_BDEV_INITIALIZED			(1 << 0)
+
+
+/**@brief	Definiton of the simple block device.*/
+struct	ext4_blockdev  {
+
+    /**@brief	Open device function
+     * @param	bdev block device.*/
+    int			(*open)(struct	ext4_blockdev *bdev);
+
+    /**@brief	Block read function.
+     * @param	bdev block device
+     * @param	buf	output buffer
+     * @param	blk_id	block id
+     * @param	blk_cnt block count*/
+    int			(*bread)(struct	ext4_blockdev *bdev, void *buf,
+                uint64_t blk_id, uint32_t blk_cnt);
+
+    /**@brief	Block write function.
+     * @param	buf input buffer
+     * @param	blk_id block id
+     * @param	blk_cnt block count*/
+    int			(*bwrite)(struct	ext4_blockdev *bdev, const void *buf,
+                uint64_t blk_id, uint32_t blk_cnt);
+
+    /**@brief	Close device function.
+     * @param	bdev block device.*/
+    int			(*close)(struct	ext4_blockdev *bdev);
+
+    /**@brief	Block size (bytes): physical*/
+    uint32_t	ph_bsize;
+
+    /**@brief	Block count: physical.*/
+    uint64_t	ph_bcnt;
+
+    /**@brief	Block size buffer: physical.*/
+    uint8_t		*ph_bbuf;
+
+    /**@brief	Block size (bytes) logical*/
+    uint32_t	lg_bsize;
+
+    /**@brief	Block count: phisical.*/
+    uint64_t	lg_bcnt;
+
+    /**@brief	Flags of te block device.*/
+    uint8_t		flags;
+
+    /**@brief	Block cache.*/
+    struct	ext4_bcache *bc;
+
+    uint8_t		cache_flush_delay;
+
+    uint32_t	bread_ctr;
+    uint32_t	bwrite_ctr;
+};
+
+
+/**@brief	Static initialization fo the block device.*/
+#define EXT4_BLOCKDEV_STATIC_INSTANCE(__name, __bsize, __bcnt, __open,  \
+                                            __bread, __bwrite, __close)	\
+        static uint8_t	__name##_ph_bbuf[(__bsize)];                    \
+        static struct	ext4_blockdev __name = {                        \
+                .open   = __open,                                       \
+                .bread  = __bread,                                      \
+                .bwrite = __bwrite,                                     \
+                .close  = __close,                                      \
+                .ph_bsize  = __bsize,                                   \
+                .ph_bcnt   = __bcnt,                                    \
+                .ph_bbuf   = __name##_ph_bbuf,                          \
+        }
+
+/**@brief	Block device initialization.
+ * @param	bdev block device descriptor
+ * @param	bg_bsize logical block size
+ * @param	bdev block device descriptor
+ * @return 	standard error code*/
+int	ext4_block_init(struct	ext4_blockdev *bdev);
+
+
+/**@brief	Binds a bcache to block device.
+ * @param	bdev block device descriptor
+ * @param	bc block cache descriptor
+ * @return 	standard error code*/
+int ext4_block_bind_bcache(struct ext4_blockdev *bdev,
+    struct ext4_bcache *bc);
+
+/**@brief	Close block device
+ * @param	bdev block device descriptor
+ * @return 	standard error code*/
+int ext4_block_fini(struct	ext4_blockdev *bdev);
+
+
+/**@brief	Set logical block size in block device.
+ * @param	bdev block device descriptor
+ * @param	lb_size ligical block size (in bytes)
+ * @return 	standard error code*/
+void ext4_block_set_lb_size(struct	ext4_blockdev *bdev,
+    uint64_t lb_bsize);
+
+/**@brief	Block get function (through cache).
+ * @param	bdev block device descriptor
+ * @param	b block descriptor
+ * @param	lba logical block address
+ * @return 	standard error code*/
+int ext4_block_get(struct	ext4_blockdev *bdev, struct	ext4_block *b,
+    uint64_t lba);
+
+/**@brief	Block set procedure (through cache).
+ * @param	bdev block device descriptor
+ * @param	b block descriptor
+ * @return 	standard error code*/
+int ext4_block_set(struct	ext4_blockdev *bdev, struct	ext4_block *b);
+
+
+/**@brief	Block read procedure (without cache)
+ * @param	bdev block device descriptor
+ * @param	buf output buffer
+ * @param	lba logical block adderss
+ * @return 	standard error code*/
+int ext4_block_get_direct(struct	ext4_blockdev *bdev, void *buf,
+    uint64_t lba);
+
+
+/**@brief	Block write procedure (without cache)
+ * @param	bdev block device descriptor
+ * @param	buf output buffer
+ * @param	lba logical block address
+ * @return 	standard error code*/
+int ext4_block_set_direct(struct	ext4_blockdev *bdev, const void *buf,
+    uint64_t lba);
+
+/**@brief	Write to block device (by direct adress).
+ * @param	bdev block device descriptor
+ * @param	off byte offset in block device
+ * @param	buf input buffer
+ * @param	len length of the write nuffer
+ * @return 	EOK when sucess*/
+int	ext4_block_writebytes(struct	ext4_blockdev *bdev, uint64_t off,
+    const void *buf, uint32_t len);
+
+
+
+/**@brief	Read freom block device (by direct adress).
+ * @param	bdev block device descriptor
+ * @param	off byte offset in block device
+ * @param	buf input buffer
+ * @param	len length of the write nuffer
+ * @return 	EOK when sucess*/
+int ext4_block_readbytes(struct	ext4_blockdev *bdev, uint64_t off,
+    void *buf, uint32_t len);
+
+/**@brief	Enable/disable delayed cache flush mode.
+ * @param	bdev block device descriptor
+ * @param	on_off
+ * 				!0 	- ENABLE
+ * 				 0	- DISABLE (all delayed cache buffers will be flushed)
+ * @return	standard error code*/
+int ext4_block_delay_cache_flush(struct	ext4_blockdev *bdev, uint8_t on_off);
+
+#endif /* EXT4_BLOCKDEV_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_config.h
@@ -1,0 +1,99 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_config.h
+ * @brief Configuration file.
+ */
+
+#ifndef EXT4_CONFIG_H_
+#define EXT4_CONFIG_H_
+
+#ifdef CONFIG_HAVE_OWN_CFG
+#include <config.h>
+#endif
+
+
+/**@brief	Enable directory indexing feature (EXT3 feature)*/
+#ifndef CONFIG_DIR_INDEX_ENABLE
+#define CONFIG_DIR_INDEX_ENABLE				0
+#endif
+
+/**@brief	Enable extents feature (EXT4 feature)*/
+#ifndef CONFIG_EXTENT_ENABLE
+#define CONFIG_EXTENT_ENABLE				0
+#endif
+
+
+
+/**@brief	Include error codes from ext4_errno or sandard library.*/
+#ifndef CONFIG_HAVE_OWN_ERRNO
+#define CONFIG_HAVE_OWN_ERRNO				1
+#endif
+
+
+/**@brief	Debug printf enable (stdout)*/
+#ifndef CONFIG_DEBUG_PRINTF
+#define CONFIG_DEBUG_PRINTF					1
+#endif
+
+/**@brief	Assert printf enable (stdout)*/
+#ifndef CONFIG_DEBUG_ASSERT
+#define CONFIG_DEBUG_ASSERT					1
+#endif
+
+/**@brief	Statistics of block device*/
+#ifndef CONFIG_BLOCK_DEV_ENABLE_STATS
+#define CONFIG_BLOCK_DEV_ENABLE_STATS		1
+#endif
+
+/**@brief	Cache size of block device.*/
+#ifndef CONFIG_BLOCK_DEV_CACHE_SIZE
+#define CONFIG_BLOCK_DEV_CACHE_SIZE			8
+#endif
+
+
+/**@brief	Ilosc urzadzen blokowych.*/
+#ifndef CONFIG_EXT4_BLOCKDEVS_COUNT
+#define CONFIG_EXT4_BLOCKDEVS_COUNT			2
+#endif
+
+/**@brief	Ilosc punktow montowania systemu plikow*/
+#ifndef CONFIG_EXT4_MOUNTPOINTS_COUNT
+#define CONFIG_EXT4_MOUNTPOINTS_COUNT		2
+#endif
+
+
+#endif /* EXT4_CONFIG_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_debug.c
@@ -1,0 +1,58 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_debug.c
+ * @brief Debug printf and assert macros.
+ */
+
+#include <ext4_config.h>
+#include <ext4_debug.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+
+static uint32_t		__dbg_mask__;
+
+
+void	ext4_dmask_set(uint32_t m)
+{
+    __dbg_mask__ = m;
+}
+
+uint32_t ext4_dmask_get(void)
+{
+    return __dbg_mask__;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_debug.h
@@ -1,0 +1,116 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_debug.c
+ * @brief Debug printf and assert macros.
+ */
+
+#ifndef EXT4_DEBUG_H_
+#define EXT4_DEBUG_H_
+
+#include <ext4_config.h>
+#include <ext4_errno.h>
+#include <stdint.h>
+#include <stdio.h>
+
+/**@brief	Debug mask: ext4_blockdev.c*/
+#define EXT4_DEBUG_BLOCKDEV			(1 << 0)
+
+/**@brief	Debug mask: ext4_fs.c*/
+#define EXT4_DEBUG_FS				(1 << 1)
+
+/**@brief	Debug mask: ext4_balloc.c*/
+#define EXT4_DEBUG_BALLOC			(1 << 2)
+
+/**@brief	Debug mask: ext4_bitmap.c*/
+#define EXT4_DEBUG_BITMAP			(1 << 3)
+
+/**@brief	Debug mask: ext4_dir_idx.c*/
+#define EXT4_DEBUG_DIR_IDX			(1 << 4)
+
+/**@brief	Debug mask: ext4_dir.c*/
+#define EXT4_DEBUG_DIR				(1 << 5)
+
+/**@brief	Debug mask: ext4_ialloc.c*/
+#define EXT4_DEBUG_IALLOC			(1 << 6)
+
+/**@brief	Debug mask: ext4_inode.c*/
+#define EXT4_DEBUG_INODE			(1 << 7)
+
+/**@brief	Debug mask: ext4_super.c*/
+#define EXT4_DEBUG_SUPER			(1 << 8)
+
+/**@brief	Debug mask: ext4_bcache.c*/
+#define EXT4_DEBUG_BCACHE			(1 << 9)
+
+
+/**@brief	All debug printf enabled.*/
+#define EXT4_DEBUG_ALL				(0xFFFFFFFF)
+
+/**@brief	Global mask debug settings.
+ * @brief	m new debug mask.*/
+void	 ext4_dmask_set(uint32_t m);
+
+/**@brief	Global debug mask get.
+ * @return	debug mask*/
+uint32_t ext4_dmask_get(void);
+
+
+#if CONFIG_DEBUG_PRINTF
+/**@brief	Debug printf.*/
+#define 	ext4_dprintf(m, ...)	do {					\
+        (m & ext4_dmask_get()) ? printf(__VA_ARGS__) : (void)0;	\
+        fflush(stdout);											\
+}while(0)
+#else
+#define 	ext4_dprintf(m, ...)
+#endif
+
+
+
+#if CONFIG_DEBUG_ASSERT
+#define 	ext4_assert(_v)	do {						                    \
+        if(!(_v)){											                \
+            printf("Assertion failed:\nModule: %s\nFunc: %s\nLine: %d\n",   \
+                    __FILE__, __FUNCTION__, __LINE__);                      \
+        }                                                                   \
+}while(0)
+#else
+#define 	ext4_assert(_v)
+#endif
+
+
+#endif /* EXT4_DEBUG_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_dir.c
@@ -1,0 +1,618 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_dir.h
+ * @brief Directory handle procedures.
+ */
+
+#include <ext4_config.h>
+#include <ext4_dir.h>
+#include <ext4_dir_idx.h>
+#include <ext4_inode.h>
+#include <ext4_fs.h>
+
+#include <string.h>
+
+uint32_t ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de)
+{
+    return to_le32(de->inode);
+}
+
+void 	 ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de,
+        uint32_t inode)
+{
+    de->inode = to_le32(inode);
+}
+
+
+uint16_t ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de)
+{
+    return to_le16(de->entry_length);
+}
+
+void 	 ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de,
+        uint16_t len)
+{
+    de->entry_length = to_le16(len);
+}
+
+
+uint16_t ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb,
+        struct ext4_directory_entry_ll *de)
+{
+    uint16_t v = de->name_length;
+
+    if ((ext4_get32(sb, rev_level) == 0) &&
+            (ext4_get32(sb, minor_rev_level) < 5))
+        v |= ((uint16_t)de->name_length_high) << 8;
+
+    return v;
+}
+void 	ext4_dir_entry_ll_set_name_length(struct ext4_sblock *sb,
+        struct ext4_directory_entry_ll *de, uint16_t len)
+{
+    de->name_length = (len << 8) >> 8;
+
+    if ((ext4_get32(sb, rev_level) == 0) &&
+            (ext4_get32(sb, minor_rev_level) < 5))
+        de->name_length_high = len >> 8;
+}
+
+
+
+uint8_t ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb,
+        struct ext4_directory_entry_ll *de)
+{
+    if ((ext4_get32(sb, rev_level) > 0) ||
+            (ext4_get32(sb, minor_rev_level) >= 5))
+        return de->inode_type;
+
+    return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
+}
+
+
+void 	ext4_dir_entry_ll_set_inode_type(struct ext4_sblock *sb,
+        struct ext4_directory_entry_ll *de, uint8_t type)
+{
+    if ((ext4_get32(sb, rev_level) > 0) ||
+            (ext4_get32(sb, minor_rev_level) >= 5))
+        de->inode_type = type;
+}
+
+/****************************************************************************/
+
+
+static int ext4_dir_iterator_set(struct ext4_directory_iterator *it,
+    uint32_t block_size)
+{
+    it->current = NULL;
+
+    uint32_t offset_in_block = it->current_offset % block_size;
+
+    /* Ensure proper alignment */
+    if ((offset_in_block % 4) != 0)
+        return EIO;
+
+    /* Ensure that the core of the entry does not overflow the block */
+    if (offset_in_block > block_size - 8)
+        return EIO;
+
+    struct ext4_directory_entry_ll *entry =
+            (void *)(it->current_block.data + offset_in_block);
+
+    /* Ensure that the whole entry does not overflow the block */
+    uint16_t length = ext4_dir_entry_ll_get_entry_length(entry);
+    if (offset_in_block + length > block_size)
+        return EIO;
+
+    /* Ensure the name length is not too large */
+    if (ext4_dir_entry_ll_get_name_length(
+            &it->inode_ref->fs->sb, entry) > length-8)
+        return EIO;
+
+    /* Everything OK - "publish" the entry */
+    it->current = entry;
+    return EOK;
+}
+
+static int ext4_dir_iterator_seek(struct ext4_directory_iterator *it,
+    uint64_t pos)
+{
+    uint64_t size = ext4_inode_get_size(&it->inode_ref->fs->sb,
+            it->inode_ref->inode);
+
+    /* The iterator is not valid until we seek to the desired position */
+    it->current = NULL;
+
+    /* Are we at the end? */
+    if (pos >= size) {
+        if (it->current_block.lb_id) {
+
+            int rc = ext4_block_set(it->inode_ref->fs->bdev,
+                    &it->current_block);
+            it->current_block.lb_id = 0;
+
+            if (rc != EOK)
+                return rc;
+        }
+
+        it->current_offset = pos;
+        return EOK;
+    }
+
+    /* Compute next block address */
+    uint32_t block_size =
+            ext4_sb_get_block_size(&it->inode_ref->fs->sb);
+    uint64_t current_block_idx = it->current_offset / block_size;
+    uint64_t next_block_idx = pos / block_size;
+
+    /*
+     * If we don't have a block or are moving accross block boundary,
+     * we need to get another block
+     */
+    if ((it->current_block.lb_id == 0) ||
+            (current_block_idx != next_block_idx)) {
+        if (it->current_block.lb_id) {
+            int rc = ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
+            it->current_block.lb_id = 0;
+
+            if (rc != EOK)
+                return rc;
+        }
+
+        uint32_t next_block_phys_idx;
+        int rc = ext4_fs_get_inode_data_block_index(it->inode_ref,
+                next_block_idx, &next_block_phys_idx);
+        if (rc != EOK)
+            return rc;
+
+
+        rc = ext4_block_get(it->inode_ref->fs->bdev, &it->current_block,
+                next_block_phys_idx);
+        if (rc != EOK) {
+            it->current_block.lb_id = 0;
+            return rc;
+        }
+    }
+
+    it->current_offset = pos;
+
+    return ext4_dir_iterator_set(it, block_size);
+}
+
+
+int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
+        struct ext4_inode_ref *inode_ref, uint64_t pos)
+{
+    it->inode_ref = inode_ref;
+    it->current = 0;
+    it->current_offset = 0;
+    it->current_block.lb_id = 0;
+
+    return ext4_dir_iterator_seek(it, pos);
+}
+
+int ext4_dir_iterator_next(struct ext4_directory_iterator *it)
+{
+    uint16_t skip = ext4_dir_entry_ll_get_entry_length(it->current);
+
+    return ext4_dir_iterator_seek(it, it->current_offset + skip);
+}
+
+int ext4_dir_iterator_fini(struct ext4_directory_iterator *it)
+{
+    it->current = 0;
+
+    if (it->current_block.lb_id)
+        return ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
+
+    return EOK;
+}
+
+void ext4_dir_write_entry(struct ext4_sblock *sb,
+    struct ext4_directory_entry_ll *entry, uint16_t entry_len,
+    struct ext4_inode_ref *child,  const char *name, size_t name_len)
+{
+    /* Check maximum entry length */
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+    ext4_assert(entry_len <= block_size);
+
+    /* Set basic attributes */
+    ext4_dir_entry_ll_set_inode(entry, child->index);
+    ext4_dir_entry_ll_set_entry_length(entry, entry_len);
+    ext4_dir_entry_ll_set_name_length(sb, entry, name_len);
+
+    /* Write name */
+    memcpy(entry->name, name, name_len);
+
+    /* Set type of entry */
+    if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY))
+        ext4_dir_entry_ll_set_inode_type(sb, entry,
+                EXT4_DIRECTORY_FILETYPE_DIR);
+    else
+        ext4_dir_entry_ll_set_inode_type(sb, entry,
+                EXT4_DIRECTORY_FILETYPE_REG_FILE);
+}
+
+int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
+        uint32_t name_len, struct ext4_inode_ref *child)
+{
+    struct ext4_fs *fs = parent->fs;
+
+#if CONFIG_DIR_INDEX_ENABLE
+    /* Index adding (if allowed) */
+    if ((ext4_sb_check_feature_compatible(&fs->sb,
+            EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
+            (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
+        int rc = ext4_dir_dx_add_entry(parent, child, name);
+
+        /* Check if index is not corrupted */
+        if (rc != EXT4_ERR_BAD_DX_DIR) {
+            if (rc != EOK)
+                return rc;
+
+            return EOK;
+        }
+
+        /* Needed to clear dir index flag if corrupted */
+        ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
+        parent->dirty = true;
+    }
+#endif
+
+    /* Linear algorithm */
+    uint32_t iblock = 0;
+    uint32_t fblock = 0;
+    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
+    uint32_t inode_size = ext4_inode_get_size(&fs->sb, parent->inode);
+    uint32_t total_blocks = inode_size / block_size;
+
+
+    /* Find block, where is space for new entry and try to add */
+    bool success = false;
+    for (iblock = 0; iblock < total_blocks; ++iblock) {
+        int rc = ext4_fs_get_inode_data_block_index(parent,
+                iblock, &fblock);
+        if (rc != EOK)
+            return rc;
+
+
+        struct ext4_block block;
+        rc = ext4_block_get(fs->bdev, &block, fblock);
+        if (rc != EOK)
+            return rc;
+
+        /* If adding is successful, function can finish */
+        rc = ext4_dir_try_insert_entry(&fs->sb, &block,
+                child, name, name_len);
+        if (rc == EOK)
+            success = true;
+
+        rc = ext4_block_set(fs->bdev, &block);
+        if (rc != EOK)
+            return rc;
+
+        if (success)
+            return EOK;
+    }
+
+    /* No free block found - needed to allocate next data block */
+
+    iblock = 0;
+    fblock = 0;
+    int rc = ext4_fs_append_inode_block(parent, &fblock, &iblock);
+    if (rc != EOK)
+        return rc;
+
+    /* Load new block */
+    struct ext4_block new_block;
+
+    rc = ext4_block_get(fs->bdev, &new_block, fblock);
+    if (rc != EOK)
+        return rc;
+
+    /* Fill block with zeroes */
+    memset(new_block.data, 0, block_size);
+    struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
+    ext4_dir_write_entry(&fs->sb, block_entry, block_size,
+            child, name, name_len);
+
+    /* Save new block */
+    new_block.dirty = true;
+    rc = ext4_block_set(fs->bdev, &new_block);
+
+    return rc;
+}
+
+int ext4_dir_find_entry(struct ext4_directory_search_result *result,
+        struct ext4_inode_ref *parent, const char *name, uint32_t name_len)
+{
+    struct ext4_sblock *sb = &parent->fs->sb;
+
+
+#if CONFIG_DIR_INDEX_ENABLE
+    /* Index search */
+    if ((ext4_sb_check_feature_compatible(sb,
+            EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
+            (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
+        int rc = ext4_dir_dx_find_entry(result, parent, name_len,
+                name);
+
+        /* Check if index is not corrupted */
+        if (rc != EXT4_ERR_BAD_DX_DIR) {
+            if (rc != EOK)
+                return rc;
+
+            return EOK;
+        }
+
+        /* Needed to clear dir index flag if corrupted */
+        ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
+        parent->dirty = true;
+    }
+#endif
+
+    /* Linear algorithm */
+
+    uint32_t iblock;
+    uint32_t fblock;
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+    uint32_t inode_size = ext4_inode_get_size(sb, parent->inode);
+    uint32_t total_blocks = inode_size / block_size;
+
+    /* Walk through all data blocks */
+    for (iblock = 0; iblock < total_blocks; ++iblock) {
+        /* Load block address */
+        int rc = ext4_fs_get_inode_data_block_index(parent, iblock,
+                &fblock);
+        if (rc != EOK)
+            return rc;
+
+        /* Load data block */
+        struct ext4_block block;
+        rc = ext4_block_get( parent->fs->bdev, &block, fblock);
+        if (rc != EOK)
+            return rc;
+
+        /* Try to find entry in block */
+        struct ext4_directory_entry_ll *res_entry;
+        rc = ext4_dir_find_in_block(&block, sb, name_len, name,
+                &res_entry);
+        if (rc == EOK) {
+            result->block = block;
+            result->dentry = res_entry;
+            return EOK;
+        }
+
+        /* Entry not found - put block and continue to the next block */
+
+        rc = ext4_block_set(parent->fs->bdev, &block);
+        if (rc != EOK)
+            return rc;
+    }
+
+    /* Entry was not found */
+
+    result->block.lb_id =  0;
+    result->dentry 		=  NULL;
+
+    return ENOENT;
+}
+
+int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
+    uint32_t name_len)
+{
+    /* Check if removing from directory */
+    if (!ext4_inode_is_type(&parent->fs->sb, parent->inode,
+            EXT4_INODE_MODE_DIRECTORY))
+        return ENOTDIR;
+
+    /* Try to find entry */
+    struct ext4_directory_search_result result;
+    int rc = ext4_dir_find_entry(&result, parent, name, name_len);
+    if (rc != EOK)
+        return rc;
+
+    /* Invalidate entry */
+    ext4_dir_entry_ll_set_inode(result.dentry, 0);
+
+    /* Store entry position in block */
+    uint32_t pos = (uint8_t *) result.dentry - result.block.data;
+
+    /*
+     * If entry is not the first in block, it must be merged
+     * with previous entry
+     */
+    if (pos != 0) {
+        uint32_t offset = 0;
+
+        /* Start from the first entry in block */
+        struct ext4_directory_entry_ll *tmp_dentry = (void *)result.block.data;
+        uint16_t tmp_dentry_length =
+                ext4_dir_entry_ll_get_entry_length(tmp_dentry);
+
+        /* Find direct predecessor of removed entry */
+        while ((offset + tmp_dentry_length) < pos) {
+            offset +=
+                    ext4_dir_entry_ll_get_entry_length(tmp_dentry);
+            tmp_dentry = (void *)(result.block.data + offset);
+            tmp_dentry_length =
+                    ext4_dir_entry_ll_get_entry_length(tmp_dentry);
+        }
+
+        ext4_assert(tmp_dentry_length + offset == pos);
+
+        /* Add to removed entry length to predecessor's length */
+        uint16_t del_entry_length =
+                ext4_dir_entry_ll_get_entry_length(result.dentry);
+        ext4_dir_entry_ll_set_entry_length(tmp_dentry,
+                tmp_dentry_length + del_entry_length);
+    }
+
+    result.block.dirty = true;
+
+    return ext4_dir_destroy_result(parent, &result);
+}
+
+int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
+    struct ext4_block *target_block, struct ext4_inode_ref *child,
+    const char *name, uint32_t name_len)
+{
+    /* Compute required length entry and align it to 4 bytes */
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+    uint16_t required_len = sizeof(struct ext4_fake_directory_entry) + name_len;
+
+    if ((required_len % 4) != 0)
+        required_len += 4 - (required_len % 4);
+
+    /* Initialize pointers, stop means to upper bound */
+    struct ext4_directory_entry_ll *dentry  = (void *)target_block->data;
+    struct ext4_directory_entry_ll *stop 	=
+            (void *)(target_block->data + block_size);
+
+    /*
+     * Walk through the block and check for invalid entries
+     * or entries with free space for new entry
+     */
+    while (dentry < stop) {
+        uint32_t inode = ext4_dir_entry_ll_get_inode(dentry);
+        uint16_t rec_len = ext4_dir_entry_ll_get_entry_length(dentry);
+
+        /* If invalid and large enough entry, use it */
+        if ((inode == 0) && (rec_len >= required_len)) {
+            ext4_dir_write_entry(sb, dentry, rec_len, child,
+                    name, name_len);
+            target_block->dirty = true;
+
+            return EOK;
+        }
+
+        /* Valid entry, try to split it */
+        if (inode != 0) {
+            uint16_t used_name_len =
+                    ext4_dir_entry_ll_get_name_length(sb, dentry);
+
+            uint16_t used_space =
+                    sizeof(struct ext4_fake_directory_entry) + used_name_len;
+
+            if ((used_name_len % 4) != 0)
+                used_space += 4 - (used_name_len % 4);
+
+            uint16_t free_space = rec_len - used_space;
+
+            /* There is free space for new entry */
+            if (free_space >= required_len) {
+                /* Cut tail of current entry */
+                ext4_dir_entry_ll_set_entry_length(dentry, used_space);
+                struct ext4_directory_entry_ll *new_entry =
+                        (void *) dentry + used_space;
+                ext4_dir_write_entry(sb, new_entry,
+                        free_space, child, name, name_len);
+
+                target_block->dirty = true;
+
+                return EOK;
+            }
+        }
+
+        /* Jump to the next entry */
+        dentry = (void *) dentry + rec_len;
+    }
+
+    /* No free space found for new entry */
+    return ENOSPC;
+}
+
+
+int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
+        size_t name_len, const char *name,
+        struct ext4_directory_entry_ll **res_entry)
+{
+    /* Start from the first entry in block */
+    struct ext4_directory_entry_ll *dentry =
+            (struct ext4_directory_entry_ll *) block->data;
+
+    /* Set upper bound for cycling */
+    uint8_t *addr_limit = block->data + ext4_sb_get_block_size(sb);
+
+    /* Walk through the block and check entries */
+    while ((uint8_t *) dentry < addr_limit) {
+        /* Termination condition */
+        if ((uint8_t *) dentry + name_len > addr_limit)
+            break;
+
+        /* Valid entry - check it */
+        if (dentry->inode != 0) {
+            /* For more effectivity compare firstly only lengths */
+            if (ext4_dir_entry_ll_get_name_length(sb, dentry) ==
+                    name_len) {
+                /* Compare names */
+                if (memcmp((uint8_t *) name, dentry->name, name_len) == 0) {
+                    *res_entry = dentry;
+                    return EOK;
+                }
+            }
+        }
+
+        uint16_t dentry_len =
+                ext4_dir_entry_ll_get_entry_length(dentry);
+
+        /* Corrupted entry */
+        if (dentry_len == 0)
+            return EINVAL;
+
+        /* Jump to next entry */
+        dentry = (struct ext4_directory_entry_ll *)
+                ((uint8_t *) dentry + dentry_len);
+    }
+
+    /* Entry not found */
+    return ENOENT;
+}
+
+int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
+    struct ext4_directory_search_result *result)
+{
+    if (result->block.lb_id)
+        return ext4_block_set(parent->fs->bdev, &result->block);
+
+    return EOK;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_dir.h
@@ -1,0 +1,114 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_dir.h
+ * @brief Directory handle procedures.
+ */
+
+#ifndef EXT4_DIR_H_
+#define EXT4_DIR_H_
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <ext4_blockdev.h>
+#include <ext4_super.h>
+
+
+#include <stdint.h>
+
+uint32_t ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de);
+
+void ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de,
+    uint32_t inode);
+
+
+uint16_t ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de);
+void ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de,
+    uint16_t len);
+
+
+uint16_t ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb,
+    struct ext4_directory_entry_ll *de);
+void ext4_dir_entry_ll_set_name_length(struct ext4_sblock *sb,
+    struct ext4_directory_entry_ll *de, uint16_t len);
+
+
+
+uint8_t ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb,
+    struct ext4_directory_entry_ll *de);
+void 	ext4_dir_entry_ll_set_inode_type(struct ext4_sblock *sb,
+    struct ext4_directory_entry_ll *de, uint8_t type);
+
+
+int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
+    struct ext4_inode_ref *inode_ref, uint64_t pos);
+
+int ext4_dir_iterator_next(struct ext4_directory_iterator *it);
+int ext4_dir_iterator_fini(struct ext4_directory_iterator *it);
+
+void ext4_dir_write_entry(struct ext4_sblock *sb,
+    struct ext4_directory_entry_ll *entry, uint16_t entry_len,
+    struct ext4_inode_ref *child,  const char *name, size_t name_len);
+
+int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
+        uint32_t name_len, struct ext4_inode_ref *child);
+
+int ext4_dir_find_entry(struct ext4_directory_search_result *result,
+        struct ext4_inode_ref *parent, const char *name, uint32_t name_len);
+
+int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
+    uint32_t name_len);
+
+int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
+    struct ext4_block *target_block, struct ext4_inode_ref *child,
+    const char *name, uint32_t name_len);
+
+int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
+    size_t name_len, const char *name,
+    struct ext4_directory_entry_ll **res_entry);
+
+int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
+    struct ext4_directory_search_result *result);
+
+
+#endif /* EXT4_DIR_H_ */
+
+/**
+ * @}
+ */
+
+
--- /dev/null
+++ b/lwext4/ext4_dir_idx.c
@@ -1,0 +1,1016 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_dir_idx.c
+ * @brief Directory indexing procedures.
+ */
+
+#include <ext4_config.h>
+#include <ext4_dir_idx.h>
+#include <ext4_dir.h>
+#include <ext4_blockdev.h>
+#include <ext4_fs.h>
+#include <ext4_super.h>
+#include <ext4_hash.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+struct ext4_dx_sort_entry {
+    uint32_t hash;
+    uint32_t rec_len;
+    void 	 *dentry;
+};
+
+static int ext4_dir_dx_hash_string(struct ext4_hash_info *hinfo, int len,
+    const char *name)
+{
+    return ext2_htree_hash(name, len, hinfo->seed, hinfo->hash_version,
+            &hinfo->hash, &hinfo->minor_hash);
+}
+
+
+uint8_t ext4_dir_dx_root_info_get_hash_version(
+        struct ext4_directory_dx_root_info *root_info)
+{
+    return root_info->hash_version;
+}
+
+
+void 	ext4_dir_dx_root_info_set_hash_version(
+        struct ext4_directory_dx_root_info  *root_info, uint8_t v)
+{
+    root_info->hash_version = v;
+}
+
+uint8_t ext4_dir_dx_root_info_get_info_length(
+        struct ext4_directory_dx_root_info *root_info)
+{
+    return root_info->info_length;
+}
+void 	ext4_dir_dx_root_info_set_info_length(
+        struct ext4_directory_dx_root_info  *root_info, uint8_t len)
+{
+    root_info->info_length = len;
+}
+
+uint8_t ext4_dir_dx_root_info_get_indirect_levels(
+        struct ext4_directory_dx_root_info *root_info)
+{
+    return root_info->indirect_levels;
+}
+
+void 	ext4_dir_dx_root_info_set_indirect_levels(
+        struct ext4_directory_dx_root_info *root_info, uint8_t lvl)
+{
+    root_info->indirect_levels = lvl;
+}
+
+
+
+uint16_t ext4_dir_dx_countlimit_get_limit(
+        struct ext4_directory_dx_countlimit *climit)
+{
+    return to_le16(climit->limit);
+}
+void 	ext4_dir_dx_countlimit_set_limit(
+        struct ext4_directory_dx_countlimit *climit, uint16_t limit)
+{
+    climit->limit = to_le16(limit);
+}
+
+uint16_t ext4_dir_dx_countlimit_get_count(
+        struct ext4_directory_dx_countlimit *climit)
+{
+    return to_le16(climit->count);
+}
+
+void 	ext4_dir_dx_countlimit_set_count(
+        struct ext4_directory_dx_countlimit *climit, uint16_t count)
+{
+    climit->count = to_le16(count);
+}
+
+
+uint32_t ext4_dir_dx_entry_get_hash(
+        struct ext4_directory_dx_entry *entry)
+{
+    return to_le32(entry->hash);
+}
+void ext4_dir_dx_entry_set_hash(
+        struct ext4_directory_dx_entry *entry, uint32_t hash)
+{
+    entry->hash = to_le32(hash);
+}
+
+uint32_t ext4_dir_dx_entry_get_block(
+        struct ext4_directory_dx_entry *entry)
+{
+    return to_le32(entry->block);
+}
+void 	ext4_dir_dx_entry_set_block(
+        struct ext4_directory_dx_entry *entry, uint32_t block)
+{
+    entry->block = to_le32(block);
+}
+/****************************************************************************/
+
+int 	ext4_dir_dx_init(struct ext4_inode_ref *dir)
+{
+    /* Load block 0, where will be index root located */
+    uint32_t fblock;
+    int rc = ext4_fs_get_inode_data_block_index(dir, 0,
+            &fblock);
+    if (rc != EOK)
+        return rc;
+
+    struct ext4_block block;
+    rc = ext4_block_get(dir->fs->bdev, &block, fblock);
+    if (rc != EOK)
+        return rc;
+
+    /* Initialize pointers to data structures */
+    struct ext4_directory_dx_root *root = (void *)block.data;
+    struct ext4_directory_dx_root_info *info = &(root->info);
+
+    /* Initialize root info structure */
+    uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version);
+
+
+    ext4_dir_dx_root_info_set_hash_version(info, hash_version);
+    ext4_dir_dx_root_info_set_indirect_levels(info, 0);
+    ext4_dir_dx_root_info_set_info_length(info, 8);
+
+    /* Set limit and current number of entries */
+    struct ext4_directory_dx_countlimit *countlimit =
+            (struct ext4_directory_dx_countlimit *) &root->entries;
+
+    ext4_dir_dx_countlimit_set_count(countlimit, 1);
+
+    uint32_t block_size =
+            ext4_sb_get_block_size(&dir->fs->sb);
+    uint32_t entry_space =
+            block_size - 2 * sizeof(struct ext4_directory_dx_dot_entry) -
+            sizeof(struct ext4_directory_dx_root_info);
+    uint16_t root_limit = entry_space / sizeof(struct ext4_directory_dx_entry);
+    ext4_dir_dx_countlimit_set_limit(countlimit, root_limit);
+
+    /* Append new block, where will be new entries inserted in the future */
+    uint32_t iblock;
+    rc = ext4_fs_append_inode_block(dir, &fblock, &iblock);
+    if (rc != EOK) {
+        ext4_block_set(dir->fs->bdev, &block);
+        return rc;
+    }
+
+    struct ext4_block new_block;
+
+    rc = ext4_block_get(dir->fs->bdev, &new_block, fblock);
+    if (rc != EOK) {
+        ext4_block_set(dir->fs->bdev, &block);
+        return rc;
+    }
+
+    /* Fill the whole block with empty entry */
+    struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
+
+    ext4_dir_entry_ll_set_entry_length(block_entry, block_size);
+    ext4_dir_entry_ll_set_inode(block_entry, 0);
+
+    new_block.dirty = true;
+    rc = ext4_block_set(dir->fs->bdev, &new_block);
+    if (rc != EOK) {
+        ext4_block_set(dir->fs->bdev, &block);
+        return rc;
+    }
+
+    /* Connect new block to the only entry in index */
+    struct ext4_directory_dx_entry *entry = root->entries;
+    ext4_dir_dx_entry_set_block(entry, iblock);
+
+    block.dirty = true;
+
+    return ext4_block_set(dir->fs->bdev, &block);
+}
+
+static int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo,
+        struct ext4_block *root_block, struct ext4_sblock *sb, size_t name_len,
+        const char *name)
+{
+    struct ext4_directory_dx_root *root =
+            (struct ext4_directory_dx_root *) root_block->data;
+
+    if ((root->info.hash_version != EXT2_HTREE_LEGACY) &&
+            (root->info.hash_version != EXT2_HTREE_HALF_MD4) &&
+            (root->info.hash_version != EXT2_HTREE_TEA))
+        return EXT4_ERR_BAD_DX_DIR;
+
+    /* Check unused flags */
+    if (root->info.unused_flags != 0)
+        return EXT4_ERR_BAD_DX_DIR;
+
+    /* Check indirect levels */
+    if (root->info.indirect_levels > 1)
+        return EXT4_ERR_BAD_DX_DIR;
+
+    /* Check if node limit is correct */
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+    uint32_t entry_space = block_size;
+    entry_space -= 2 * sizeof(struct ext4_directory_dx_dot_entry);
+    entry_space -= sizeof(struct ext4_directory_dx_root_info);
+    entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
+
+    uint16_t limit = ext4_dir_dx_countlimit_get_limit(
+            (struct ext4_directory_dx_countlimit *) &root->entries);
+    if (limit != entry_space)
+        return EXT4_ERR_BAD_DX_DIR;
+
+    /* Check hash version and modify if necessary */
+    hinfo->hash_version =
+            ext4_dir_dx_root_info_get_hash_version(&root->info);
+    if ((hinfo->hash_version <= EXT2_HTREE_TEA) &&
+            (ext4_sb_check_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
+        /* Use unsigned hash */
+        hinfo->hash_version += 3;
+    }
+
+    /* Load hash seed from superblock */
+
+    hinfo->seed = ext4_get8(sb, hash_seed);
+
+    /* Compute hash value of name */
+    if (name)
+        return ext4_dir_dx_hash_string(hinfo, name_len, name);
+
+    return EOK;
+}
+
+
+static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo,
+        struct ext4_inode_ref *inode_ref, struct ext4_block *root_block,
+        struct ext4_directory_dx_block **dx_block,
+        struct ext4_directory_dx_block *dx_blocks)
+{
+    struct ext4_directory_dx_block *tmp_dx_block = dx_blocks;
+    struct ext4_directory_dx_root *root =
+            (struct ext4_directory_dx_root *) root_block->data;
+    struct ext4_directory_dx_entry *entries =
+            (struct ext4_directory_dx_entry *) &root->entries;
+
+    uint16_t limit = ext4_dir_dx_countlimit_get_limit(
+            (struct ext4_directory_dx_countlimit *) entries);
+    uint8_t indirect_level =
+            ext4_dir_dx_root_info_get_indirect_levels(&root->info);
+
+    struct ext4_block *tmp_block = root_block;
+    struct ext4_directory_dx_entry *p;
+    struct ext4_directory_dx_entry *q;
+    struct ext4_directory_dx_entry *m;
+    struct ext4_directory_dx_entry *at;
+
+    /* Walk through the index tree */
+    while (true) {
+        uint16_t count = ext4_dir_dx_countlimit_get_count(
+                (struct ext4_directory_dx_countlimit *) entries);
+        if ((count == 0) || (count > limit))
+            return EXT4_ERR_BAD_DX_DIR;
+
+        /* Do binary search in every node */
+        p = entries + 1;
+        q = entries + count - 1;
+
+        while (p <= q) {
+            m = p + (q - p) / 2;
+            if (ext4_dir_dx_entry_get_hash(m) > hinfo->hash)
+                q = m - 1;
+            else
+                p = m + 1;
+        }
+
+        at = p - 1;
+
+        /* Write results */
+
+        memcpy(&tmp_dx_block->block, tmp_block, sizeof(struct ext4_block));
+        tmp_dx_block->entries = entries;
+        tmp_dx_block->position = at;
+
+        /* Is algorithm in the leaf? */
+        if (indirect_level == 0) {
+            *dx_block = tmp_dx_block;
+            return EOK;
+        }
+
+        /* Goto child node */
+        uint32_t next_block = ext4_dir_dx_entry_get_block(at);
+
+        indirect_level--;
+
+        uint32_t fblock;
+        int rc = ext4_fs_get_inode_data_block_index(inode_ref,
+                next_block, &fblock);
+        if (rc != EOK)
+            return rc;
+
+        rc = ext4_block_get(inode_ref->fs->bdev, tmp_block, fblock);
+        if (rc != EOK)
+            return rc;
+
+        entries = ((struct ext4_directory_dx_node *) tmp_block->data)->entries;
+        limit = ext4_dir_dx_countlimit_get_limit(
+                (struct ext4_directory_dx_countlimit *) entries);
+
+        uint16_t entry_space =
+                ext4_sb_get_block_size(&inode_ref->fs->sb) -
+                sizeof(struct ext4_directory_dx_dot_entry);
+
+        entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
+
+        if (limit != entry_space) {
+            ext4_block_set(inode_ref->fs->bdev, tmp_block);
+            return EXT4_ERR_BAD_DX_DIR;
+        }
+
+        ++tmp_dx_block;
+    }
+
+    /* Unreachable */
+    return EOK;
+}
+
+static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref,
+        uint32_t hash, struct ext4_directory_dx_block *dx_block,
+        struct ext4_directory_dx_block *dx_blocks)
+{
+    uint32_t num_handles = 0;
+    struct ext4_directory_dx_block *p = dx_block;
+
+    /* Try to find data block with next bunch of entries */
+    while (true) {
+        p->position++;
+        uint16_t count = ext4_dir_dx_countlimit_get_count(
+                (struct ext4_directory_dx_countlimit *) p->entries);
+
+        if (p->position < p->entries + count)
+            break;
+
+        if (p == dx_blocks)
+            return EOK;
+
+        num_handles++;
+        p--;
+    }
+
+    /* Check hash collision (if not occured - no next block cannot be used)*/
+    uint32_t current_hash = ext4_dir_dx_entry_get_hash(p->position);
+    if ((hash & 1) == 0) {
+        if ((current_hash & ~1) != hash)
+            return 0;
+    }
+
+    /* Fill new path */
+    while (num_handles--) {
+        uint32_t block_idx =
+                ext4_dir_dx_entry_get_block(p->position);
+        uint32_t block_addr;
+
+        int rc = ext4_fs_get_inode_data_block_index(inode_ref,
+                block_idx, &block_addr);
+        if (rc != EOK)
+            return rc;
+
+
+        struct ext4_block block;
+        rc = ext4_block_get(inode_ref->fs->bdev, &block, block_addr);
+        if (rc != EOK)
+            return rc;
+
+        p++;
+
+        /* Don't forget to put old block (prevent memory leak) */
+        ext4_block_set(inode_ref->fs->bdev, &p->block);
+
+
+
+        memcpy(&p->block, &p->block, sizeof(block));
+        p->entries = ((struct ext4_directory_dx_node *) block.data)->entries;
+        p->position = p->entries;
+    }
+
+    return ENOENT;
+}
+
+
+
+int 	ext4_dir_dx_find_entry(struct ext4_directory_search_result * result,
+        struct ext4_inode_ref *inode_ref, size_t name_len, const char *name)
+{
+    /* Load direct block 0 (index root) */
+    uint32_t root_block_addr;
+    int rc = ext4_fs_get_inode_data_block_index(inode_ref, 0,
+            &root_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    struct ext4_fs *fs = inode_ref->fs;
+
+    struct ext4_block root_block;
+    rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Initialize hash info (compute hash value) */
+    struct ext4_hash_info hinfo;
+    rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb,
+            name_len, name);
+    if (rc != EOK) {
+        ext4_block_set(fs->bdev, &root_block);
+        return EXT4_ERR_BAD_DX_DIR;
+    }
+
+    /*
+     * Hardcoded number 2 means maximum height of index tree,
+     * specified in the Linux driver.
+     */
+    struct ext4_directory_dx_block dx_blocks[2];
+    struct ext4_directory_dx_block *dx_block;
+    struct ext4_directory_dx_block *tmp;
+
+    rc = ext4_dir_dx_get_leaf(&hinfo, inode_ref, &root_block,
+            &dx_block, dx_blocks);
+    if (rc != EOK) {
+        ext4_block_set(fs->bdev, &root_block);
+        return EXT4_ERR_BAD_DX_DIR;
+    }
+
+    do {
+        /* Load leaf block */
+        uint32_t leaf_block_idx =
+                ext4_dir_dx_entry_get_block(dx_block->position);
+        uint32_t leaf_block_addr;
+
+        rc = ext4_fs_get_inode_data_block_index(inode_ref,
+                leaf_block_idx, &leaf_block_addr);
+        if (rc != EOK)
+            goto cleanup;
+
+        struct ext4_block leaf_block;
+        rc = ext4_block_get(fs->bdev, &leaf_block, leaf_block_addr);
+        if (rc != EOK)
+            goto cleanup;
+
+        /* Linear search inside block */
+        struct ext4_directory_entry_ll *res_dentry;
+        rc = ext4_dir_find_in_block(&leaf_block, &fs->sb,
+                name_len, name, &res_dentry);
+
+        /* Found => return it */
+        if (rc == EOK) {
+            result->block = leaf_block;
+            result->dentry = res_dentry;
+            goto cleanup;
+        }
+
+        /* Not found, leave untouched */
+        ext4_block_set(fs->bdev, &leaf_block);
+
+        if (rc != ENOENT)
+            goto cleanup;
+
+        /* check if the next block could be checked */
+        rc = ext4_dir_dx_next_block(inode_ref, hinfo.hash,
+                dx_block, &dx_blocks[0]);
+        if (rc < 0)
+            goto cleanup;
+    } while (rc == ENOENT);
+
+    /* Entry not found */
+    rc = ENOENT;
+
+    cleanup:
+    /* The whole path must be released (preventing memory leak) */
+    tmp = dx_blocks;
+
+    while (tmp <= dx_block) {
+        ext4_block_set(fs->bdev, &tmp->block);
+        ++tmp;
+    }
+
+    return rc;
+}
+
+static int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2)
+{
+    struct ext4_dx_sort_entry *entry1 = (void *)arg1;
+    struct ext4_dx_sort_entry *entry2 = (void *)arg2;
+
+    if (entry1->hash == entry2->hash)
+        return 0;
+
+    if (entry1->hash < entry2->hash)
+        return -1;
+    else
+        return 1;
+}
+
+static void ext4_dir_dx_insert_entry(
+        struct ext4_directory_dx_block *index_block, uint32_t hash,
+        uint32_t iblock)
+{
+    struct ext4_directory_dx_entry *old_index_entry = index_block->position;
+    struct ext4_directory_dx_entry *new_index_entry = old_index_entry + 1;
+
+    struct ext4_directory_dx_countlimit *countlimit =
+            (struct ext4_directory_dx_countlimit *) index_block->entries;
+    uint32_t count = ext4_dir_dx_countlimit_get_count(countlimit);
+
+    struct ext4_directory_dx_entry *start_index = index_block->entries;
+    size_t bytes = (void *) (start_index + count) - (void *) (new_index_entry);
+
+    memmove(new_index_entry + 1, new_index_entry, bytes);
+
+    ext4_dir_dx_entry_set_block(new_index_entry, iblock);
+    ext4_dir_dx_entry_set_hash(new_index_entry, hash);
+
+    ext4_dir_dx_countlimit_set_count(countlimit, count + 1);
+
+    index_block->block.dirty = true;
+}
+
+static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref,
+        struct ext4_hash_info *hinfo, struct ext4_block *old_data_block,
+        struct ext4_directory_dx_block *index_block,
+        struct ext4_block *new_data_block)
+{
+    int rc = EOK;
+
+    /* Allocate buffer for directory entries */
+    uint32_t block_size =
+            ext4_sb_get_block_size(&inode_ref->fs->sb);
+
+    void *entry_buffer = malloc(block_size);
+    if (entry_buffer == NULL)
+        return ENOMEM;
+
+    /* dot entry has the smallest size available */
+    uint32_t max_entry_count =
+            block_size / sizeof(struct ext4_directory_dx_dot_entry);
+
+    /* Allocate sort entry */
+    struct ext4_dx_sort_entry *sort_array =
+            malloc(max_entry_count * sizeof(struct ext4_dx_sort_entry));
+
+    if (sort_array == NULL) {
+        free(entry_buffer);
+        return ENOMEM;
+    }
+
+    uint32_t idx = 0;
+    uint32_t real_size = 0;
+
+    /* Initialize hinfo */
+    struct ext4_hash_info tmp_hinfo;
+    memcpy(&tmp_hinfo, hinfo, sizeof(struct ext4_hash_info));
+
+    /* Load all valid entries to the buffer */
+    struct ext4_directory_entry_ll *dentry = (void *)old_data_block->data;
+    void *entry_buffer_ptr = entry_buffer;
+    while ((void *)dentry < (void *)(old_data_block->data + block_size)) {
+        /* Read only valid entries */
+        if (ext4_dir_entry_ll_get_inode(dentry) != 0) {
+            uint8_t len = ext4_dir_entry_ll_get_name_length(
+                    &inode_ref->fs->sb, dentry);
+
+            rc = ext4_dir_dx_hash_string(&tmp_hinfo, len, (char*)dentry->name);
+            if(rc != EOK) {
+                free(sort_array);
+                free(entry_buffer);
+                return rc;
+            }
+
+            uint32_t rec_len = 8 + len;
+
+            if ((rec_len % 4) != 0)
+                rec_len += 4 - (rec_len % 4);
+
+            memcpy(entry_buffer_ptr, dentry, rec_len);
+
+            sort_array[idx].dentry = entry_buffer_ptr;
+            sort_array[idx].rec_len = rec_len;
+            sort_array[idx].hash = tmp_hinfo.hash;
+
+            entry_buffer_ptr += rec_len;
+            real_size += rec_len;
+            idx++;
+        }
+
+        dentry = (void *) dentry +
+                ext4_dir_entry_ll_get_entry_length(dentry);
+    }
+
+    /* Sort all entries */
+    qsort(sort_array, idx, sizeof(struct ext4_dx_sort_entry),
+            ext4_dir_dx_entry_comparator);
+
+    /* Allocate new block for store the second part of entries */
+    uint32_t new_fblock;
+    uint32_t new_iblock;
+    rc = ext4_fs_append_inode_block(inode_ref, &new_fblock,
+            &new_iblock);
+    if (rc != EOK) {
+        free(sort_array);
+        free(entry_buffer);
+        return rc;
+    }
+
+    /* Load new block */
+    struct ext4_block new_data_block_tmp;
+    rc = ext4_block_get(inode_ref->fs->bdev, &new_data_block_tmp,
+            new_fblock);
+    if (rc != EOK) {
+        free(sort_array);
+        free(entry_buffer);
+        return rc;
+    }
+
+    /*
+     * Distribute entries to two blocks (by size)
+     * - compute the half
+     */
+    uint32_t new_hash = 0;
+    uint32_t current_size = 0;
+    uint32_t mid = 0;
+    uint32_t i;
+    for ( i = 0; i < idx; ++i) {
+        if ((current_size + sort_array[i].rec_len) > (real_size / 2)) {
+            new_hash = sort_array[i].hash;
+            mid = i;
+            break;
+        }
+
+        current_size += sort_array[i].rec_len;
+    }
+
+    /* Check hash collision */
+    uint32_t continued = 0;
+    if (new_hash == sort_array[mid-1].hash)
+        continued = 1;
+
+    uint32_t offset = 0;
+    void *ptr;
+
+    /* First part - to the old block */
+    for (i = 0; i < mid; ++i) {
+        ptr = old_data_block->data + offset;
+        memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
+
+        struct ext4_directory_entry_ll *tmp = ptr;
+        if (i < (mid - 1))
+            ext4_dir_entry_ll_set_entry_length(tmp,
+                    sort_array[i].rec_len);
+        else
+            ext4_dir_entry_ll_set_entry_length(tmp,
+                    block_size - offset);
+
+        offset += sort_array[i].rec_len;
+    }
+
+    /* Second part - to the new block */
+    offset = 0;
+    for (i = mid; i < idx; ++i) {
+        ptr = new_data_block_tmp.data + offset;
+        memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
+
+        struct ext4_directory_entry_ll *tmp = ptr;
+        if (i < (idx - 1))
+            ext4_dir_entry_ll_set_entry_length(tmp,
+                    sort_array[i].rec_len);
+        else
+            ext4_dir_entry_ll_set_entry_length(tmp,
+                    block_size - offset);
+
+        offset += sort_array[i].rec_len;
+    }
+
+    /* Do some steps to finish operation */
+    old_data_block->dirty = true;
+    new_data_block_tmp.dirty = true;
+
+    free(sort_array);
+    free(entry_buffer);
+
+    ext4_dir_dx_insert_entry(index_block, new_hash + continued,
+            new_iblock);
+
+    *new_data_block = new_data_block_tmp;
+
+    return EOK;
+}
+
+/** Split index node and maybe some parent nodes in the tree hierarchy.
+ *
+ * @param inode_ref Directory i-node
+ * @param dx_blocks Array with path from root to leaf node
+ * @param dx_block  Leaf block to be split if needed
+ *
+ * @return Error code
+ *
+ */
+static int ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref,
+        struct  ext4_directory_dx_block *dx_blocks,
+        struct ext4_directory_dx_block *dx_block)
+{
+    struct ext4_directory_dx_entry *entries;
+    if (dx_block == dx_blocks)
+        entries =
+                ((struct  ext4_directory_dx_root *) dx_block->block.data)->entries;
+    else
+        entries =
+                ((struct ext4_directory_dx_node *) dx_block->block.data)->entries;
+
+    struct ext4_directory_dx_countlimit *countlimit =
+            (struct ext4_directory_dx_countlimit *) entries;
+
+    uint16_t leaf_limit =
+            ext4_dir_dx_countlimit_get_limit(countlimit);
+    uint16_t leaf_count =
+            ext4_dir_dx_countlimit_get_count(countlimit);
+
+    /* Check if is necessary to split index block */
+    if (leaf_limit == leaf_count) {
+        size_t levels = dx_block - dx_blocks;
+
+        struct ext4_directory_dx_entry *root_entries =
+                ((struct ext4_directory_dx_root *) dx_blocks[0].block.data)->entries;
+
+        struct ext4_directory_dx_countlimit *root_countlimit =
+                (struct ext4_directory_dx_countlimit *) root_entries;
+        uint16_t root_limit =
+                ext4_dir_dx_countlimit_get_limit(root_countlimit);
+        uint16_t root_count =
+                ext4_dir_dx_countlimit_get_count(root_countlimit);
+
+        /* Linux limitation */
+        if ((levels > 0) && (root_limit == root_count))
+            return ENOSPC;
+
+        /* Add new block to directory */
+        uint32_t new_fblock;
+        uint32_t new_iblock;
+        int rc = ext4_fs_append_inode_block(inode_ref,
+                &new_fblock, &new_iblock);
+        if (rc != EOK)
+            return rc;
+
+        /* load new block */
+        struct ext4_block new_block;
+        rc = ext4_block_get(inode_ref->fs->bdev, &new_block,
+                new_fblock);
+        if (rc != EOK)
+            return rc;
+
+        struct ext4_directory_dx_node  *new_node 	= (void *)new_block.data;
+        struct ext4_directory_dx_entry *new_entries = new_node->entries;
+
+        uint32_t block_size =
+                ext4_sb_get_block_size(&inode_ref->fs->sb);
+
+        /* Split leaf node */
+        if (levels > 0) {
+            uint32_t count_left = leaf_count / 2;
+            uint32_t count_right = leaf_count - count_left;
+            uint32_t hash_right =
+                    ext4_dir_dx_entry_get_hash(entries + count_left);
+
+            /* Copy data to new node */
+            memcpy((void *) new_entries, (void *) (entries + count_left),
+                    count_right * sizeof(struct ext4_directory_dx_entry));
+
+            /* Initialize new node */
+            struct ext4_directory_dx_countlimit *left_countlimit =
+                    (struct ext4_directory_dx_countlimit *) entries;
+            struct ext4_directory_dx_countlimit *right_countlimit =
+                    (struct ext4_directory_dx_countlimit *) new_entries;
+
+            ext4_dir_dx_countlimit_set_count(left_countlimit, count_left);
+            ext4_dir_dx_countlimit_set_count(right_countlimit, count_right);
+
+            uint32_t entry_space =
+                    block_size - sizeof(struct ext4_fake_directory_entry);
+            uint32_t node_limit =
+                    entry_space / sizeof(struct ext4_directory_dx_entry);
+            ext4_dir_dx_countlimit_set_limit(right_countlimit, node_limit);
+
+            /* Which index block is target for new entry */
+            uint32_t position_index = (dx_block->position - dx_block->entries);
+            if (position_index >= count_left) {
+                dx_block->block.dirty = true;
+
+                struct ext4_block block_tmp = dx_block->block;
+
+
+                dx_block->block = new_block;
+
+                dx_block->position =
+                        new_entries + position_index - count_left;
+                dx_block->entries = new_entries;
+
+                new_block = block_tmp;
+            }
+
+            /* Finally insert new entry */
+            ext4_dir_dx_insert_entry(dx_blocks, hash_right, new_iblock);
+
+            return ext4_block_set(inode_ref->fs->bdev, &new_block);
+        } else {
+            /* Create second level index */
+
+            /* Copy data from root to child block */
+            memcpy((void *) new_entries, (void *) entries,
+                    leaf_count * sizeof(struct ext4_directory_dx_entry));
+
+            struct ext4_directory_dx_countlimit *new_countlimit =
+                    (struct ext4_directory_dx_countlimit *) new_entries;
+
+            uint32_t entry_space =
+                    block_size - sizeof(struct ext4_fake_directory_entry);
+            uint32_t node_limit =
+                    entry_space / sizeof(struct ext4_directory_dx_entry);
+            ext4_dir_dx_countlimit_set_limit(new_countlimit, node_limit);
+
+            /* Set values in root node */
+            struct ext4_directory_dx_countlimit *new_root_countlimit =
+                    (struct ext4_directory_dx_countlimit *) entries;
+
+            ext4_dir_dx_countlimit_set_count(new_root_countlimit, 1);
+            ext4_dir_dx_entry_set_block(entries, new_iblock);
+
+            ((struct ext4_directory_dx_root *)
+                    dx_blocks[0].block.data)->info.indirect_levels = 1;
+
+            /* Add new entry to the path */
+            dx_block = dx_blocks + 1;
+            dx_block->position = dx_block->position - entries + new_entries;
+            dx_block->entries = new_entries;
+            dx_block->block = new_block;
+        }
+    }
+
+    return EOK;
+}
+
+int 	ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
+        struct ext4_inode_ref *child, const char *name)
+{
+    int rc2 = EOK;
+
+    /* Get direct block 0 (index root) */
+    uint32_t root_block_addr;
+    int rc = ext4_fs_get_inode_data_block_index(parent, 0,
+            &root_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    struct ext4_fs *fs = parent->fs;
+    struct ext4_block root_block;
+
+    rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Initialize hinfo structure (mainly compute hash) */
+    uint32_t name_len = strlen(name);
+    struct ext4_hash_info hinfo;
+    rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb,
+            name_len, name);
+    if (rc != EOK) {
+        ext4_block_set(fs->bdev, &root_block);
+        return EXT4_ERR_BAD_DX_DIR;
+    }
+
+    /*
+     * Hardcoded number 2 means maximum height of index
+     * tree defined in Linux.
+     */
+    struct ext4_directory_dx_block dx_blocks[2];
+    struct ext4_directory_dx_block *dx_block;
+    struct ext4_directory_dx_block *dx_it;
+
+    rc = ext4_dir_dx_get_leaf(&hinfo, parent, &root_block,
+            &dx_block, dx_blocks);
+    if (rc != EOK) {
+        rc = EXT4_ERR_BAD_DX_DIR;
+        goto release_index;
+    }
+
+    /* Try to insert to existing data block */
+    uint32_t leaf_block_idx =
+            ext4_dir_dx_entry_get_block(dx_block->position);
+    uint32_t leaf_block_addr;
+    rc = ext4_fs_get_inode_data_block_index(parent, leaf_block_idx,
+            &leaf_block_addr);
+    if (rc != EOK)
+        goto release_index;
+
+    struct ext4_block target_block;
+    rc = ext4_block_get(fs->bdev, &target_block, leaf_block_addr);
+    if (rc != EOK)
+        goto release_index;
+
+    /* Check if insert operation passed */
+    rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child,
+            name, name_len);
+    if (rc == EOK)
+        goto release_target_index;
+
+    /*
+     * Check if there is needed to split index node
+     * (and recursively also parent nodes)
+     */
+    rc = ext4_dir_dx_split_index(parent, dx_blocks, dx_block);
+    if (rc != EOK)
+        goto release_target_index;
+
+    /* Split entries to two blocks (includes sorting by hash value) */
+    struct ext4_block new_block;
+    rc = ext4_dir_dx_split_data(parent, &hinfo, &target_block,
+            dx_block, &new_block);
+    if (rc != EOK) {
+        rc2 = rc;
+        goto release_target_index;
+    }
+
+    /* Where to save new entry */
+    uint32_t new_block_hash =
+            ext4_dir_dx_entry_get_hash(dx_block->position + 1);
+    if (hinfo.hash >= new_block_hash)
+        rc = ext4_dir_try_insert_entry(&fs->sb, &new_block,
+                child, name, name_len);
+    else
+        rc = ext4_dir_try_insert_entry(&fs->sb, &target_block,
+                child, name, name_len);
+
+    /* Cleanup */
+    rc = ext4_block_set(fs->bdev, &new_block);
+    if (rc != EOK)
+        return rc;
+
+    /* Cleanup operations */
+
+    release_target_index:
+    rc2 = rc;
+
+    rc = ext4_block_set(fs->bdev, &target_block);
+    if (rc != EOK)
+        return rc;
+
+    release_index:
+    if (rc != EOK)
+        rc2 = rc;
+
+    dx_it = dx_blocks;
+
+    while (dx_it <= dx_block) {
+        rc = ext4_block_set(fs->bdev, &dx_it->block);
+        if (rc != EOK)
+            return rc;
+
+        dx_it++;
+    }
+
+    return rc2;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_dir_idx.h
@@ -1,0 +1,103 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_dir_idx.h
+ * @brief Directory indexing procedures.
+ */
+
+#ifndef EXT4_DIR_IDX_H_
+#define EXT4_DIR_IDX_H_
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+uint8_t ext4_dir_dx_root_info_get_hash_version(
+        struct ext4_directory_dx_root_info *root_info);
+void 	ext4_dir_dx_root_info_set_hash_version(
+        struct ext4_directory_dx_root_info  *root_info, uint8_t v);
+
+uint8_t ext4_dir_dx_root_info_get_info_length(
+        struct ext4_directory_dx_root_info *root_info);
+void 	ext4_dir_dx_root_info_set_info_length(
+        struct ext4_directory_dx_root_info  *root_info, uint8_t len);
+
+uint8_t ext4_dir_dx_root_info_get_indirect_levels(
+        struct ext4_directory_dx_root_info *root_info);
+void 	ext4_dir_dx_root_info_set_indirect_levels(
+        struct ext4_directory_dx_root_info *root_info, uint8_t lvl);
+
+
+
+uint16_t ext4_dir_dx_countlimit_get_limit(
+        struct ext4_directory_dx_countlimit *climit);
+void 	ext4_dir_dx_countlimit_set_limit(
+        struct ext4_directory_dx_countlimit *climit, uint16_t limit);
+
+uint16_t ext4_dir_dx_countlimit_get_count(
+        struct ext4_directory_dx_countlimit *climit);
+void 	ext4_dir_dx_countlimit_set_count(
+        struct ext4_directory_dx_countlimit *climit, uint16_t count);
+
+
+uint32_t ext4_dir_dx_entry_get_hash(
+        struct ext4_directory_dx_entry *entry);
+void ext4_dir_dx_entry_set_hash(
+        struct ext4_directory_dx_entry *entry, uint32_t hash);
+
+uint32_t ext4_dir_dx_entry_get_block(
+        struct ext4_directory_dx_entry *entry);
+void 	ext4_dir_dx_entry_set_block(
+        struct ext4_directory_dx_entry *entry, uint32_t block);
+
+
+int 	ext4_dir_dx_init(struct ext4_inode_ref *dir);
+
+int 	ext4_dir_dx_find_entry(struct ext4_directory_search_result * result,
+        struct ext4_inode_ref *inode_ref, size_t name_len, const char *name);
+
+int 	ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
+        struct ext4_inode_ref *child, const char *name);
+
+#endif /* EXT4_DIR_IDX_H_ */
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_errno.h
@@ -1,0 +1,92 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_errno.h
+ * @brief Error codes.
+ */
+#ifndef EXT4_ERRNO_H_
+#define EXT4_ERRNO_H_
+
+#include <ext4_config.h>
+
+#ifndef CONFIG_HAVE_OWN_ERRNO
+#include <errno.h>
+#else
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO			 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Argument list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+
+#define	ENOTSUP		95
+#endif
+
+/**@brief	OK return value*/
+#ifndef EOK
+#define EOK			0
+#endif
+
+#endif /* EXT4_ERRNO_H_ */
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_fs.c
@@ -1,0 +1,1189 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_fs.c
+ * @brief More complex filesystem functions.
+ */
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <ext4_fs.h>
+#include <ext4_errno.h>
+#include <ext4_blockdev.h>
+#include <ext4_super.h>
+#include <ext4_debug.h>
+#include <ext4_block_group.h>
+#include <ext4_balloc.h>
+#include <ext4_bitmap.h>
+#include <ext4_inode.h>
+#include <ext4_ialloc.h>
+#include <string.h>
+
+int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev)
+{
+    int r, i;
+    uint16_t tmp;
+    uint32_t bsize;
+    bool read_only = false;
+
+    ext4_assert(fs && bdev);
+
+    fs->bdev = bdev;
+
+    r = ext4_sb_read(fs->bdev, &fs->sb);
+    if(r != EOK)
+        return r;
+
+    if(!ext4_sb_check(&fs->sb))
+        return ENOTSUP;
+
+    bsize = ext4_sb_get_block_size(&fs->sb);
+    if (bsize > EXT4_MAX_BLOCK_SIZE)
+        return ENXIO;
+
+    r = ext4_fs_check_features(fs, &read_only);
+    if(r != EOK)
+        return r;
+
+    if(read_only)
+        return ENOTSUP;
+
+    /* Compute limits for indirect block levels */
+    uint32_t blocks_id = bsize / sizeof(uint32_t);
+
+    fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT;
+    fs->inode_blocks_per_level[0] = 1;
+
+    for (i = 1; i < 4; i++) {
+        fs->inode_blocks_per_level[i] = fs->inode_blocks_per_level[i - 1] *
+                blocks_id;
+        fs->inode_block_limits[i] = fs->inode_block_limits[i - 1] +
+                fs->inode_blocks_per_level[i];
+    }
+
+    /*Validate FS*/
+    tmp = ext4_get16(&fs->sb, state);
+    if (tmp & EXT4_SUPERBLOCK_STATE_ERROR_FS) {
+        ext4_dprintf(EXT4_DEBUG_FS,
+                "Filesystem was not cleanly unmounted before \n");
+    }
+
+    /* Mark system as mounted */
+    ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS);
+    r = ext4_sb_write(fs->bdev, &fs->sb);
+    if (r != EOK)
+        return r;
+
+
+    /*Update mount count*/
+    ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1);
+
+    return r;
+}
+
+
+int ext4_fs_fini(struct ext4_fs *fs)
+{
+    ext4_assert(fs);
+
+    /*Set superblock state*/
+    ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_VALID_FS);
+
+    return ext4_sb_write(fs->bdev, &fs->sb);
+}
+
+int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only)
+{
+    ext4_assert(fs && read_only);
+
+    if(ext4_get32(&fs->sb, rev_level) == 0){
+        *read_only = false;
+        return EOK;
+    }
+
+    /*Check features_incompatible*/
+    if ((ext4_get32(&fs->sb, features_incompatible) &
+            (~EXT4_FEATURE_INCOMPAT_SUPP)) )
+        return ENOTSUP;
+
+
+    /*Check features_read_only*/
+    if ((ext4_get32(&fs->sb, features_read_only) &
+            (~EXT4_FEATURE_RO_COMPAT_SUPP))){
+        *read_only = true;
+        return EOK;
+    }
+
+    *read_only = false;
+
+    return EOK;
+}
+
+uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr)
+{
+    ext4_assert(baddr);
+    if(ext4_get32(s, first_data_block))
+        baddr--;
+
+    return  baddr % ext4_get32(s, blocks_per_group);
+}
+
+
+
+uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
+    uint32_t bgid)
+{
+    if(ext4_get32(s, first_data_block))
+        index++;
+
+    return ext4_get32(s, blocks_per_group) * bgid + index;
+}
+
+
+
+
+static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)
+{
+    uint32_t i;
+    uint32_t bitmap_block_addr = ext4_bg_get_block_bitmap(
+            bg_ref->block_group, &bg_ref->fs->sb);
+
+    struct ext4_block block_bitmap;
+    int rc = ext4_block_get(bg_ref->fs->bdev, &block_bitmap,
+            bitmap_block_addr);
+    if (rc != EOK)
+        return rc;
+
+
+    memset(block_bitmap.data, 0, ext4_sb_get_block_size(&bg_ref->fs->sb));
+
+    /* Determine first block and first data block in group */
+    uint32_t first_idx = 0;
+
+    uint32_t first_data = ext4_balloc_get_first_data_block_in_group(
+            &bg_ref->fs->sb, bg_ref);
+    uint32_t first_data_idx = ext4_fs_baddr2_index_in_group(
+            &bg_ref->fs->sb, first_data);
+
+    /*Set bits from to first block to first data block - 1 to one (allocated)*/
+    /*TODO: Optimize it*/
+    for (i = first_idx; i < first_data_idx; ++i)
+        ext4_bmap_bit_set(block_bitmap.data, i);
+
+
+    block_bitmap.dirty = true;
+
+    /* Save bitmap */
+    return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
+}
+
+static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref)
+{
+    /* Load bitmap */
+    uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(
+            bg_ref->block_group, &bg_ref->fs->sb);
+
+    struct ext4_block block_bitmap;
+    int rc = ext4_block_get(bg_ref->fs->bdev, &block_bitmap,
+            bitmap_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Initialize all bitmap bits to zero */
+    uint32_t block_size = ext4_sb_get_block_size(&bg_ref->fs->sb);
+    uint32_t inodes_per_group = ext4_get32(&bg_ref->fs->sb, inodes_per_group);
+
+    memset(block_bitmap.data, 0, (inodes_per_group + 7) / 8);
+
+    uint32_t start_bit = inodes_per_group;
+    uint32_t end_bit = block_size * 8;
+
+    uint32_t i;
+    for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+        ext4_bmap_bit_set(block_bitmap.data, i);
+
+    if (i < end_bit)
+        memset(block_bitmap.data + (i >> 3), 0xff, (end_bit - i) >> 3);
+
+    block_bitmap.dirty = true;
+
+    /* Save bitmap */
+    return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
+}
+
+static int ext4_fs_init_inode_table(struct ext4_block_group_ref *bg_ref)
+{
+    struct ext4_sblock *sb = &bg_ref->fs->sb;
+
+    uint32_t inode_size 	  = ext4_get32(sb, inode_size);
+    uint32_t block_size 	  = ext4_sb_get_block_size(sb);
+    uint32_t inodes_per_block = block_size / inode_size;
+    uint32_t inodes_in_group  = ext4_inodes_in_group_cnt(sb, bg_ref->index);
+    uint32_t table_blocks = inodes_in_group / inodes_per_block;
+    uint32_t fblock;
+
+    if (inodes_in_group % inodes_per_block)
+        table_blocks++;
+
+    /* Compute initialization bounds */
+    uint32_t first_block = ext4_bg_get_inode_table_first_block(
+            bg_ref->block_group, sb);
+
+    uint32_t last_block = first_block + table_blocks - 1;
+
+    /* Initialization of all itable blocks */
+    for (fblock = first_block; fblock <= last_block; ++fblock) {
+
+        struct ext4_block block;
+        int rc = ext4_block_get(bg_ref->fs->bdev, &block, fblock);
+        if (rc != EOK)
+            return rc;
+
+        memset(block.data, 0, block_size);
+        block.dirty = true;
+
+        ext4_block_set(bg_ref->fs->bdev, &block);
+        if (rc != EOK)
+            return rc;
+    }
+
+    return EOK;
+}
+
+
+int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
+    struct ext4_block_group_ref *ref)
+{
+    /* Compute number of descriptors, that fits in one data block */
+    uint32_t dsc_per_block = ext4_sb_get_block_size(&fs->sb) /
+            ext4_sb_get_desc_size(&fs->sb);
+
+    /* Block group descriptor table starts at the next block after superblock */
+    uint64_t block_id = ext4_get32(&fs->sb, first_data_block) + 1;
+
+    /* Find the block containing the descriptor we are looking for */
+    block_id += bgid / dsc_per_block;
+    uint32_t offset = (bgid % dsc_per_block) *
+            ext4_sb_get_desc_size(&fs->sb);
+
+
+    int rc = ext4_block_get(fs->bdev, &ref->block, block_id);
+    if (rc != EOK)
+        return rc;
+
+    ref->block_group = (void *)(ref->block.data + offset);
+    ref->fs = fs;
+    ref->index = bgid;
+    ref->dirty = false;
+
+    if (ext4_bg_has_flag(ref->block_group,
+            EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
+        rc = ext4_fs_init_block_bitmap(ref);
+        if (rc != EOK) {
+            ext4_block_set(fs->bdev, &ref->block);
+            return rc;
+        }
+        ext4_bg_clear_flag(ref->block_group,
+            EXT4_BLOCK_GROUP_BLOCK_UNINIT);
+
+        ref->dirty = true;
+    }
+
+    if (ext4_bg_has_flag(ref->block_group,
+            EXT4_BLOCK_GROUP_INODE_UNINIT)) {
+        rc = ext4_fs_init_inode_bitmap(ref);
+        if (rc != EOK) {
+            ext4_block_set(ref->fs->bdev, &ref->block);
+            return rc;
+        }
+
+        ext4_bg_clear_flag(ref->block_group,
+            EXT4_BLOCK_GROUP_INODE_UNINIT);
+
+        if (!ext4_bg_has_flag(ref->block_group,
+                EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
+            rc = ext4_fs_init_inode_table(ref);
+            if (rc != EOK){
+                ext4_block_set(fs->bdev, &ref->block);
+                return rc;
+            }
+
+            ext4_bg_set_flag(ref->block_group,
+                EXT4_BLOCK_GROUP_ITABLE_ZEROED);
+        }
+
+        ref->dirty = true;
+    }
+
+    return EOK;
+}
+
+static uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid,
+    struct ext4_bgroup *bg)
+{
+    /* If checksum not supported, 0 will be returned */
+    uint16_t crc = 0;
+
+    /* Compute the checksum only if the filesystem supports it */
+    if (ext4_sb_check_read_only(sb,
+            EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+        void *base = bg;
+        void *checksum = &bg->checksum;
+
+        uint32_t offset = (uint32_t) (checksum - base);
+
+        /* Convert block group index to little endian */
+        uint32_t le_group = to_le32(bgid);
+
+        /* Initialization */
+        crc = ext4_bg_crc16(~0, sb->uuid, sizeof(sb->uuid));
+
+        /* Include index of block group */
+        crc = ext4_bg_crc16(crc, (uint8_t *) &le_group, sizeof(le_group));
+
+        /* Compute crc from the first part (stop before checksum field) */
+        crc = ext4_bg_crc16(crc, (uint8_t *) bg, offset);
+
+        /* Skip checksum */
+        offset += sizeof(bg->checksum);
+
+        /* Checksum of the rest of block group descriptor */
+        if ((ext4_sb_check_feature_incompatible(sb,
+                EXT4_FEATURE_INCOMPAT_64BIT)) &&
+                (offset < ext4_sb_get_desc_size(sb)))
+
+            crc = ext4_bg_crc16(crc, ((uint8_t *) bg) + offset,
+                    ext4_sb_get_desc_size(sb) - offset);
+    }
+    return crc;
+}
+
+int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref)
+{
+    /* Check if reference modified */
+    if (ref->dirty) {
+        /* Compute new checksum of block group */
+        uint16_t checksum =
+                ext4_fs_bg_checksum(&ref->fs->sb, ref->index,
+                        ref->block_group);
+
+        ref->block_group->checksum = to_le16(checksum);
+
+        /* Mark block dirty for writing changes to physical device */
+        ref->block.dirty = true;
+    }
+
+    /* Put back block, that contains block group descriptor */
+    return ext4_block_set(ref->fs->bdev, &ref->block);
+}
+
+int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
+    struct ext4_inode_ref *ref)
+{
+    /* Compute number of i-nodes, that fits in one data block */
+    uint32_t inodes_per_group = ext4_get32(&fs->sb, inodes_per_group);
+
+    /*
+     * Inode numbers are 1-based, but it is simpler to work with 0-based
+     * when computing indices
+     */
+    index -= 1;
+    uint32_t block_group = index / inodes_per_group;
+    uint32_t offset_in_group = index % inodes_per_group;
+
+    /* Load block group, where i-node is located */
+    struct ext4_block_group_ref bg_ref;
+
+    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
+    if (rc != EOK) {
+        return rc;
+    }
+
+    /* Load block address, where i-node table is located */
+    uint32_t inode_table_start =
+            ext4_bg_get_inode_table_first_block(bg_ref.block_group,
+                    &fs->sb);
+
+    /* Put back block group reference (not needed more) */
+    rc = ext4_fs_put_block_group_ref(&bg_ref);
+    if (rc != EOK) {
+        return rc;
+    }
+
+    /* Compute position of i-node in the block group */
+    uint16_t inode_size = ext4_get16(&fs->sb, inode_size);
+    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
+    uint32_t byte_offset_in_group = offset_in_group * inode_size;
+
+    /* Compute block address */
+    uint64_t block_id = inode_table_start +
+            (byte_offset_in_group / block_size);
+
+
+    rc = ext4_block_get(fs->bdev, &ref->block, block_id);
+    if (rc != EOK) {
+        return rc;
+    }
+
+    /* Compute position of i-node in the data block */
+    uint32_t offset_in_block = byte_offset_in_group % block_size;
+    ref->inode = (struct ext4_inode *)(ref->block.data + offset_in_block);
+
+    /* We need to store the original value of index in the reference */
+    ref->index = index + 1;
+    ref->fs = fs;
+    ref->dirty = false;
+
+    return EOK;
+}
+
+int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref)
+{
+    /* Check if reference modified */
+    if (ref->dirty) {
+        /* Mark block dirty for writing changes to physical device */
+        ref->block.dirty = true;
+    }
+
+    /* Put back block, that contains i-node */
+    return  ext4_block_set(ref->fs->bdev, &ref->block);
+}
+
+int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
+    bool is_directory)
+{
+    /* Check if newly allocated i-node will be a directory */
+    uint32_t i;
+    bool is_dir;
+
+    is_dir = is_directory;
+
+    /* Allocate inode by allocation algorithm */
+    uint32_t index;
+    int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
+    if (rc != EOK)
+        return rc;
+
+    /* Load i-node from on-disk i-node table */
+    rc = ext4_fs_get_inode_ref(fs, index, inode_ref);
+    if (rc != EOK) {
+        ext4_ialloc_free_inode(fs, index, is_dir);
+        return rc;
+    }
+
+    /* Initialize i-node */
+    struct ext4_inode *inode = inode_ref->inode;
+
+    uint16_t mode;
+    if (is_dir) {
+        /*
+         * Default directory permissions to be compatible with other systems
+         * 0777 (octal) == rwxrwxrwx
+         */
+
+        mode = 0777;
+        mode |= EXT4_INODE_MODE_DIRECTORY;
+        ext4_inode_set_mode(&fs->sb, inode, mode);
+        ext4_inode_set_links_count(inode, 1);  /* '.' entry */
+
+    } else {
+        /*
+         * Default file permissions to be compatible with other systems
+         * 0666 (octal) == rw-rw-rw-
+         */
+
+        mode = 0666;
+        mode |= EXT4_INODE_MODE_FILE;
+        ext4_inode_set_mode(&fs->sb, inode, mode);
+        ext4_inode_set_links_count(inode, 0);
+    }
+
+    ext4_inode_set_uid(inode, 0);
+    ext4_inode_set_gid(inode, 0);
+    ext4_inode_set_size(inode, 0);
+    ext4_inode_set_access_time(inode, 		0);
+    ext4_inode_set_change_inode_time(inode, 0);
+    ext4_inode_set_modification_time(inode, 0);
+    ext4_inode_set_deletion_time(inode, 	0);
+    ext4_inode_set_blocks_count(&fs->sb, inode, 0);
+    ext4_inode_set_flags(inode, 0);
+    ext4_inode_set_generation(inode, 0);
+
+    /* Reset blocks array */
+    for (i = 0; i < EXT4_INODE_BLOCKS; i++)
+        inode->blocks[i] = 0;
+
+#if 0
+    /* Initialize extents if needed */
+    if (ext4_sb_check_feature_incompatible(
+            &fs->sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS);
+
+
+        /* Initialize extent root header */
+        ext4_extent_header_t *header = ext4_inode_get_extent_header(inode);
+        ext4_extent_header_set_depth(header, 0);
+        ext4_extent_header_set_entries_count(header, 0);
+        ext4_extent_header_set_generation(header, 0);
+        ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC);
+
+        uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) -
+                sizeof(ext4_extent_header_t)) / sizeof(ext4_extent_t);
+
+        ext4_extent_header_set_max_entries_count(header, max_entries);
+    }
+#endif
+
+    inode_ref->dirty = true;
+
+    return EOK;
+}
+
+int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref)
+{
+    struct ext4_fs *fs = inode_ref->fs;
+    uint32_t offset;
+    uint32_t suboffset;
+    /* For extents must be data block destroyed by other way */
+    if ((ext4_sb_check_feature_incompatible(&fs->sb,
+            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))){
+        /* Data structures are released during truncate operation... */
+        goto finish;
+    }
+
+    /* Release all indirect (no data) blocks */
+
+    /* 1) Single indirect */
+    uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
+    if (fblock != 0) {
+        int rc = ext4_balloc_free_block(inode_ref, fblock);
+        if (rc != EOK)
+            return rc;
+
+        ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
+    }
+
+    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
+    uint32_t count = block_size / sizeof(uint32_t);
+
+    struct	ext4_block  block;
+
+    /* 2) Double indirect */
+    fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
+    if (fblock != 0) {
+        int rc = ext4_block_get(fs->bdev, &block, fblock);
+        if (rc != EOK)
+            return rc;
+
+        uint32_t ind_block;
+        for (offset = 0; offset < count; ++offset) {
+            ind_block = to_le32(((uint32_t *) block.data)[offset]);
+
+            if (ind_block != 0) {
+                rc = ext4_balloc_free_block(inode_ref, ind_block);
+                if (rc != EOK) {
+                    ext4_block_set(fs->bdev, &block);
+                    return rc;
+                }
+            }
+        }
+
+        ext4_block_set(fs->bdev, &block);
+        rc = ext4_balloc_free_block(inode_ref, fblock);
+        if (rc != EOK)
+            return rc;
+
+        ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);
+    }
+
+    /* 3) Tripple indirect */
+    struct	ext4_block  subblock;
+    fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
+    if (fblock != 0) {
+        int rc = ext4_block_get(fs->bdev, &block, fblock);
+        if (rc != EOK)
+            return rc;
+
+        uint32_t ind_block;
+        for ( offset = 0; offset < count; ++offset) {
+            ind_block = to_le32(((uint32_t *) block.data)[offset]);
+
+            if (ind_block != 0) {
+                rc = ext4_block_get(fs->bdev, &subblock, ind_block);
+                if (rc != EOK) {
+                    ext4_block_set(fs->bdev, &block);
+                    return rc;
+                }
+
+                uint32_t ind_subblock;
+                for (suboffset = 0; suboffset < count;
+                        ++suboffset) {
+                    ind_subblock = to_le32(((uint32_t *)
+                            subblock.data)[suboffset]);
+
+                    if (ind_subblock != 0) {
+                        rc = ext4_balloc_free_block(inode_ref, ind_subblock);
+                        if (rc != EOK) {
+                            ext4_block_set(fs->bdev, &subblock);
+                            ext4_block_set(fs->bdev, &block);
+                            return rc;
+                        }
+                    }
+                }
+
+                ext4_block_set(fs->bdev, &subblock);
+
+
+                rc = ext4_balloc_free_block(inode_ref, ind_block);
+                if (rc != EOK) {
+                    ext4_block_set(fs->bdev, &block);
+                    return rc;
+                }
+            }
+        }
+
+        ext4_block_set(fs->bdev, &block);
+        rc = ext4_balloc_free_block(inode_ref, fblock);
+        if (rc != EOK)
+            return rc;
+
+        ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);
+    }
+
+    finish:
+    /* Mark inode dirty for writing to the physical device */
+    inode_ref->dirty = true;
+
+    /* Free block with extended attributes if present */
+    uint32_t xattr_block = ext4_inode_get_file_acl(
+            inode_ref->inode, &fs->sb);
+    if (xattr_block) {
+        int rc = ext4_balloc_free_block(inode_ref, xattr_block);
+        if (rc != EOK)
+            return rc;
+
+        ext4_inode_set_file_acl(inode_ref->inode, &fs->sb, 0);
+    }
+
+    /* Free inode by allocator */
+    int rc;
+    if (ext4_inode_is_type(&fs->sb, inode_ref->inode,
+            EXT4_INODE_MODE_DIRECTORY))
+        rc = ext4_ialloc_free_inode(fs, inode_ref->index, true);
+    else
+        rc = ext4_ialloc_free_inode(fs, inode_ref->index, false);
+
+    return rc;
+}
+
+int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref,
+    uint64_t new_size)
+{
+    struct ext4_sblock *sb = &inode_ref->fs->sb;
+    uint32_t i;
+
+    /* Check flags, if i-node can be truncated */
+    if (!ext4_inode_can_truncate(sb, inode_ref->inode))
+        return EINVAL;
+
+    /* If sizes are equal, nothing has to be done. */
+    uint64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);
+    if (old_size == new_size)
+        return EOK;
+
+    /* It's not suppported to make the larger file by truncate operation */
+    if (old_size < new_size)
+        return EINVAL;
+
+    /* Compute how many blocks will be released */
+    uint64_t size_diff = old_size - new_size;
+    uint32_t block_size  = ext4_sb_get_block_size(sb);
+    uint32_t diff_blocks_count = size_diff / block_size;
+    if (size_diff % block_size != 0)
+        diff_blocks_count++;
+
+    uint32_t old_blocks_count = old_size / block_size;
+    if (old_size % block_size != 0)
+        old_blocks_count++;
+
+    if ((ext4_sb_check_feature_incompatible(sb,
+            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
+#if 0
+        /* Extents require special operation */
+        int rc = ext4_extent_release_blocks_from(inode_ref,
+                old_blocks_count - diff_blocks_count);
+        if (rc != EOK)
+            return rc;
+#endif
+    } else {
+        /* Release data blocks from the end of file */
+
+        /* Starting from 1 because of logical blocks are numbered from 0 */
+        for (i = 1; i <= diff_blocks_count; ++i) {
+            int rc = ext4_fs_release_inode_block(inode_ref,
+                    old_blocks_count - i);
+            if (rc != EOK)
+                return rc;
+        }
+    }
+
+    /* Update i-node */
+    ext4_inode_set_size(inode_ref->inode, new_size);
+    inode_ref->dirty = true;
+
+    return EOK;
+}
+
+int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref,
+    uint64_t iblock, uint32_t *fblock)
+{
+    struct ext4_fs *fs = inode_ref->fs;
+
+    /* For empty file is situation simple */
+    if (ext4_inode_get_size(&fs->sb, inode_ref->inode) == 0) {
+        *fblock = 0;
+        return EOK;
+    }
+
+    uint32_t current_block;
+
+    /* Handle i-node using extents */
+    if ((ext4_sb_check_feature_incompatible(&fs->sb,
+            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
+
+#if 0
+        int rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
+        if (rc != EOK)
+            return rc;
+
+        *fblock = current_block;
+        return EOK;
+#endif
+    }
+
+    struct ext4_inode *inode = inode_ref->inode;
+
+    /* Direct block are read directly from array in i-node structure */
+    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
+        current_block = ext4_inode_get_direct_block(inode, (uint32_t) iblock);
+        *fblock = current_block;
+        return EOK;
+    }
+
+    /* Determine indirection level of the target block */
+    unsigned int level = 0;
+    unsigned int i;
+    for (i = 1; i < 4; i++) {
+        if (iblock < fs->inode_block_limits[i]) {
+            level = i;
+            break;
+        }
+    }
+
+    if (level == 0)
+        return EIO;
+
+    /* Compute offsets for the topmost level */
+    uint64_t block_offset_in_level =
+            iblock - fs->inode_block_limits[level - 1];
+    current_block = ext4_inode_get_indirect_block(inode, level - 1);
+    uint32_t offset_in_block =
+            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+
+    /* Sparse file */
+    if (current_block == 0) {
+        *fblock = 0;
+        return EOK;
+    }
+
+    struct	ext4_block block;
+
+    /*
+     * Navigate through other levels, until we find the block number
+     * or find null reference meaning we are dealing with sparse file
+     */
+    while (level > 0) {
+        /* Load indirect block */
+        int rc = ext4_block_get(fs->bdev, &block, current_block);
+        if (rc != EOK)
+            return rc;
+
+        /* Read block address from indirect block */
+        current_block =
+                to_le32(((uint32_t *) block.data)[offset_in_block]);
+
+        /* Put back indirect block untouched */
+        rc = ext4_block_set(fs->bdev, &block);
+        if (rc != EOK)
+            return rc;
+
+        /* Check for sparse file */
+        if (current_block == 0) {
+            *fblock = 0;
+            return EOK;
+        }
+
+        /* Jump to the next level */
+        level--;
+
+        /* Termination condition - we have address of data block loaded */
+        if (level == 0)
+            break;
+
+        /* Visit the next level */
+        block_offset_in_level %= fs->inode_blocks_per_level[level];
+        offset_in_block =
+                block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+    }
+
+    *fblock = current_block;
+
+    return EOK;
+}
+
+int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
+    uint64_t iblock, uint32_t fblock)
+{
+    struct ext4_fs *fs = inode_ref->fs;
+
+    /* Handle inode using extents */
+    if ((ext4_sb_check_feature_incompatible(&fs->sb,
+            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
+        /* Not reachable */
+        return ENOTSUP;
+    }
+
+    /* Handle simple case when we are dealing with direct reference */
+    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
+        ext4_inode_set_direct_block(inode_ref->inode, (uint32_t) iblock,
+                fblock);
+        inode_ref->dirty = true;
+
+        return EOK;
+    }
+
+    /* Determine the indirection level needed to get the desired block */
+    unsigned int level = 0;
+    unsigned int i;
+    for (i = 1; i < 4; i++) {
+        if (iblock < fs->inode_block_limits[i]) {
+            level = i;
+            break;
+        }
+    }
+
+    if (level == 0)
+        return EIO;
+
+    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
+
+    /* Compute offsets for the topmost level */
+    uint64_t block_offset_in_level =
+            iblock - fs->inode_block_limits[level - 1];
+    uint32_t current_block =
+            ext4_inode_get_indirect_block(inode_ref->inode, level - 1);
+    uint32_t offset_in_block =
+            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+
+    uint32_t new_block_addr;
+
+    struct	ext4_block block;
+    struct	ext4_block new_block;
+
+    /* Is needed to allocate indirect block on the i-node level */
+    if (current_block == 0) {
+        /* Allocate new indirect block */
+        int rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
+        if (rc != EOK)
+            return rc;
+
+        /* Update i-node */
+        ext4_inode_set_indirect_block(inode_ref->inode, level - 1,
+            new_block_addr);
+        inode_ref->dirty = true;
+
+        /* Load newly allocated block */
+        rc = ext4_block_get(fs->bdev, &new_block, new_block_addr);
+        if (rc != EOK) {
+            ext4_balloc_free_block(inode_ref, new_block_addr);
+            return rc;
+        }
+
+        /* Initialize new block */
+        memset(new_block.data, 0, block_size);
+        new_block.dirty = true;
+
+        /* Put back the allocated block */
+        rc = ext4_block_set(fs->bdev, &new_block);
+        if (rc != EOK)
+            return rc;
+
+        current_block = new_block_addr;
+    }
+
+    /*
+     * Navigate through other levels, until we find the block number
+     * or find null reference meaning we are dealing with sparse file
+     */
+    while (level > 0) {
+        int rc = ext4_block_get(fs->bdev, &block, current_block);
+        if (rc != EOK)
+            return rc;
+
+        current_block =
+                to_le32(((uint32_t *) block.data)[offset_in_block]);
+
+        if ((level > 1) && (current_block == 0)) {
+            /* Allocate new block */
+            rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
+            if (rc != EOK) {
+                ext4_block_set(fs->bdev, &block);
+                return rc;
+            }
+
+            /* Load newly allocated block */
+            rc = ext4_block_get(fs->bdev, &new_block, new_block_addr);
+
+            if (rc != EOK) {
+                ext4_block_set(fs->bdev, &block);
+                return rc;
+            }
+
+            /* Initialize allocated block */
+            memset(new_block.data, 0, block_size);
+            new_block.dirty = true;
+
+            rc = ext4_block_set(fs->bdev, &new_block);
+            if (rc != EOK) {
+                ext4_block_set(fs->bdev, &block);
+                return rc;
+            }
+
+            /* Write block address to the parent */
+            ((uint32_t *) block.data)[offset_in_block] =
+                    to_le32(new_block_addr);
+            block.dirty = true;
+            current_block = new_block_addr;
+        }
+
+        /* Will be finished, write the fblock address */
+        if (level == 1) {
+            ((uint32_t *) block.data)[offset_in_block] =
+                    to_le32(fblock);
+            block.dirty = true;
+        }
+
+        rc = ext4_block_set(fs->bdev, &block);
+        if (rc != EOK)
+            return rc;
+
+        level--;
+
+        /*
+         * If we are on the last level, break here as
+         * there is no next level to visit
+         */
+        if (level == 0)
+            break;
+
+        /* Visit the next level */
+        block_offset_in_level %= fs->inode_blocks_per_level[level];
+        offset_in_block =
+                block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+    }
+
+    return EOK;
+}
+
+int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
+    uint32_t iblock)
+{
+    uint32_t fblock;
+
+    struct ext4_fs *fs = inode_ref->fs;
+
+    /* Extents are handled otherwise = there is not support in this function */
+    ext4_assert(!(ext4_sb_check_feature_incompatible(&fs->sb,
+            EXT4_FEATURE_INCOMPAT_EXTENTS) &&
+            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));
+
+    struct ext4_inode *inode = inode_ref->inode;
+
+    /* Handle simple case when we are dealing with direct reference */
+    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
+        fblock = ext4_inode_get_direct_block(inode, iblock);
+
+        /* Sparse file */
+        if (fblock == 0)
+            return EOK;
+
+        ext4_inode_set_direct_block(inode, iblock, 0);
+        return ext4_balloc_free_block(inode_ref, fblock);
+    }
+
+    /* Determine the indirection level needed to get the desired block */
+    unsigned int level = 0;
+    unsigned int i;
+    for (i = 1; i < 4; i++) {
+        if (iblock < fs->inode_block_limits[i]) {
+            level = i;
+            break;
+        }
+    }
+
+    if (level == 0)
+        return EIO;
+
+    /* Compute offsets for the topmost level */
+    uint64_t block_offset_in_level =
+            iblock - fs->inode_block_limits[level - 1];
+    uint32_t current_block =
+            ext4_inode_get_indirect_block(inode, level - 1);
+    uint32_t offset_in_block =
+            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+
+    /*
+     * Navigate through other levels, until we find the block number
+     * or find null reference meaning we are dealing with sparse file
+     */
+    struct	ext4_block block;
+
+    while (level > 0) {
+
+        /* Sparse check */
+        if (current_block == 0)
+            return EOK;
+
+        int rc = ext4_block_get(fs->bdev, &block, current_block);
+        if (rc != EOK)
+            return rc;
+
+        current_block =
+                to_le32(((uint32_t *) block.data)[offset_in_block]);
+
+        /* Set zero if physical data block address found */
+        if (level == 1) {
+            ((uint32_t *) block.data)[offset_in_block] =
+                    to_le32(0);
+            block.dirty = true;
+        }
+
+        rc = ext4_block_set(fs->bdev, &block);
+        if (rc != EOK)
+            return rc;
+
+        level--;
+
+        /*
+         * If we are on the last level, break here as
+         * there is no next level to visit
+         */
+        if (level == 0)
+            break;
+
+        /* Visit the next level */
+        block_offset_in_level %= fs->inode_blocks_per_level[level];
+        offset_in_block =
+                block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+    }
+
+    fblock = current_block;
+    if (fblock == 0)
+        return EOK;
+
+    /* Physical block is not referenced, it can be released */
+    return ext4_balloc_free_block(inode_ref, fblock);
+}
+
+
+int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
+    uint32_t *fblock, uint32_t *iblock)
+{
+    /* Handle extents separately */
+    if ((ext4_sb_check_feature_incompatible(&inode_ref->fs->sb,
+            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))){
+
+#if 0
+        return ext4_extent_append_block(inode_ref, iblock, fblock, true);
+#endif
+    }
+
+    struct ext4_sblock *sb = &inode_ref->fs->sb;
+
+    /* Compute next block index and allocate data block */
+    uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
+    uint32_t block_size = ext4_sb_get_block_size(sb);
+
+    /* Align size i-node size */
+    if ((inode_size % block_size) != 0)
+        inode_size += block_size - (inode_size % block_size);
+
+    /* Logical blocks are numbered from 0 */
+    uint32_t new_block_idx = inode_size / block_size;
+
+    /* Allocate new physical block */
+    uint32_t phys_block;
+    int rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
+    if (rc != EOK)
+        return rc;
+
+    /* Add physical block address to the i-node */
+    rc = ext4_fs_set_inode_data_block_index(inode_ref,
+            new_block_idx, phys_block);
+    if (rc != EOK) {
+        ext4_balloc_free_block(inode_ref, phys_block);
+        return rc;
+    }
+
+    /* Update i-node */
+    ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
+    inode_ref->dirty = true;
+
+    *fblock = phys_block;
+    *iblock = new_block_idx;
+
+    return EOK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_fs.h
@@ -1,0 +1,95 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_fs.c
+ * @brief More complex filesystem functions.
+ */
+
+#ifndef EXT4_FS_H_
+#define EXT4_FS_H_
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev);
+int ext4_fs_fini(struct ext4_fs *fs);
+
+int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only);
+
+
+uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr);
+uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
+    uint32_t bgid);
+
+
+int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
+    struct ext4_block_group_ref *ref);
+int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref);
+
+
+int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
+    struct ext4_inode_ref *ref);
+int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref);
+
+
+int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
+    bool is_directory);
+int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref);
+
+int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref,
+        uint64_t new_size);
+
+int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref,
+        uint64_t iblock, uint32_t *fblock);
+
+int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
+        uint64_t iblock, uint32_t fblock);
+
+int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
+        uint32_t iblock);
+
+int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
+        uint32_t *fblock, uint32_t *iblock);
+
+#endif /* EXT4_FS_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_hash.c
@@ -1,0 +1,320 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ * FreeBSD:
+ * Copyright (c) 2010, 2013 Zheng Liu <lz@freebsd.org>
+ * Copyright (c) 2012, Vyacheslav Matyushin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ */
+
+/*
+ * The following notice applies to the code in ext2_half_md4():
+ *
+ * Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD4 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+/** @addtogroup lwext4
+ * @{
+ */
+/**
+ * @file  ext4_hash.c
+ * @brief Directory indexing hash functions.
+ */
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <string.h>
+#include <ext4_errno.h>
+
+/* F, G, and H are MD4 functions */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+/*
+ * FF, GG, and HH are transformations for rounds 1, 2, and 3.
+ * Rotation is separated from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s) { \
+        (a) += F ((b), (c), (d)) + (x); \
+        (a) = ROTATE_LEFT ((a), (s)); \
+}
+
+#define GG(a, b, c, d, x, s) { \
+        (a) += G ((b), (c), (d)) + (x) + (uint32_t)0x5A827999; \
+        (a) = ROTATE_LEFT ((a), (s)); \
+}
+
+#define HH(a, b, c, d, x, s) { \
+        (a) += H ((b), (c), (d)) + (x) + (uint32_t)0x6ED9EBA1; \
+        (a) = ROTATE_LEFT ((a), (s)); \
+}
+
+/*
+ * MD4 basic transformation.  It transforms state based on block.
+ *
+ * This is a half md4 algorithm since Linux uses this algorithm for dir
+ * index.  This function is derived from the RSA Data Security, Inc. MD4
+ * Message-Digest Algorithm and was modified as necessary.
+ *
+ * The return value of this function is uint32_t in Linux, but actually we don't
+ * need to check this value, so in our version this function doesn't return any
+ * value.
+ */
+static void
+ext2_half_md4(uint32_t hash[4], uint32_t data[8])
+{
+    uint32_t a = hash[0], b = hash[1], c = hash[2], d = hash[3];
+
+    /* Round 1 */
+    FF(a, b, c, d, data[0],  3);
+    FF(d, a, b, c, data[1],  7);
+    FF(c, d, a, b, data[2], 11);
+    FF(b, c, d, a, data[3], 19);
+    FF(a, b, c, d, data[4],  3);
+    FF(d, a, b, c, data[5],  7);
+    FF(c, d, a, b, data[6], 11);
+    FF(b, c, d, a, data[7], 19);
+
+    /* Round 2 */
+    GG(a, b, c, d, data[1],  3);
+    GG(d, a, b, c, data[3],  5);
+    GG(c, d, a, b, data[5],  9);
+    GG(b, c, d, a, data[7], 13);
+    GG(a, b, c, d, data[0],  3);
+    GG(d, a, b, c, data[2],  5);
+    GG(c, d, a, b, data[4],  9);
+    GG(b, c, d, a, data[6], 13);
+
+    /* Round 3 */
+    HH(a, b, c, d, data[3],  3);
+    HH(d, a, b, c, data[7],  9);
+    HH(c, d, a, b, data[2], 11);
+    HH(b, c, d, a, data[6], 15);
+    HH(a, b, c, d, data[1],  3);
+    HH(d, a, b, c, data[5],  9);
+    HH(c, d, a, b, data[0], 11);
+    HH(b, c, d, a, data[4], 15);
+
+    hash[0] += a;
+    hash[1] += b;
+    hash[2] += c;
+    hash[3] += d;
+}
+
+/*
+ * Tiny Encryption Algorithm.
+ */
+static void
+ext2_tea(uint32_t hash[4], uint32_t data[8])
+{
+    uint32_t tea_delta = 0x9E3779B9;
+    uint32_t sum;
+    uint32_t x = hash[0], y = hash[1];
+    int n = 16;
+    int i = 1;
+
+    while (n-- > 0) {
+        sum = i * tea_delta;
+        x += ((y << 4) + data[0]) ^ (y + sum) ^ ((y >> 5) + data[1]);
+        y += ((x << 4) + data[2]) ^ (x + sum) ^ ((x >> 5) + data[3]);
+        i++;
+    }
+
+    hash[0] += x;
+    hash[1] += y;
+}
+
+static uint32_t
+ext2_legacy_hash(const char *name, int len, int unsigned_char)
+{
+    uint32_t h0, h1 = 0x12A3FE2D, h2 = 0x37ABE8F9;
+    uint32_t multi = 0x6D22F5;
+    const unsigned char *uname = (const unsigned char *)name;
+    const signed char *sname = (const signed char *)name;
+    int val, i;
+
+    for (i = 0; i < len; i++) {
+        if (unsigned_char)
+            val = (unsigned int)*uname++;
+        else
+            val = (int)*sname++;
+
+        h0 = h2 + (h1 ^ (val * multi));
+        if (h0 & 0x80000000)
+            h0 -= 0x7FFFFFFF;
+        h2 = h1;
+        h1 = h0;
+    }
+
+    return (h1 << 1);
+}
+
+static void
+ext2_prep_hashbuf(const char *src, int slen, uint32_t *dst, int dlen,
+        int unsigned_char)
+{
+    uint32_t padding = slen | (slen << 8) | (slen << 16) | (slen << 24);
+    uint32_t buf_val;
+    int len, i;
+    int buf_byte;
+    const unsigned char *ubuf = (const unsigned char *)src;
+    const signed char *sbuf = (const signed char *)src;
+
+    if (slen > dlen)
+        len = dlen;
+    else
+        len = slen;
+
+    buf_val = padding;
+
+    for (i = 0; i < len; i++) {
+        if (unsigned_char)
+            buf_byte = (unsigned int)ubuf[i];
+        else
+            buf_byte = (int)sbuf[i];
+
+        if ((i % 4) == 0)
+            buf_val = padding;
+
+        buf_val <<= 8;
+        buf_val += buf_byte;
+
+        if ((i % 4) == 3) {
+            *dst++ = buf_val;
+            dlen -= sizeof(uint32_t);
+            buf_val = padding;
+        }
+    }
+
+    dlen -= sizeof(uint32_t);
+    if (dlen >= 0)
+        *dst++ = buf_val;
+
+    dlen -= sizeof(uint32_t);
+    while (dlen >= 0) {
+        *dst++ = padding;
+        dlen -= sizeof(uint32_t);
+    }
+}
+
+int
+ext2_htree_hash(const char *name, int len,
+        const uint32_t *hash_seed, int hash_version,
+        uint32_t *hash_major, uint32_t *hash_minor)
+{
+    uint32_t hash[4];
+    uint32_t data[8];
+    uint32_t major = 0, minor = 0;
+    int unsigned_char = 0;
+
+    if (!name || !hash_major)
+        return (-1);
+
+    if (len < 1 || len > 255)
+        goto error;
+
+    hash[0] = 0x67452301;
+    hash[1] = 0xEFCDAB89;
+    hash[2] = 0x98BADCFE;
+    hash[3] = 0x10325476;
+
+    if (hash_seed)
+        memcpy(hash, hash_seed, sizeof(hash));
+
+    switch (hash_version) {
+    case EXT2_HTREE_TEA_UNSIGNED:
+        unsigned_char = 1;
+    case EXT2_HTREE_TEA:
+        while (len > 0) {
+            ext2_prep_hashbuf(name, len, data, 16, unsigned_char);
+            ext2_tea(hash, data);
+            len -= 16;
+            name += 16;
+        }
+        major = hash[0];
+        minor = hash[1];
+        break;
+    case EXT2_HTREE_LEGACY_UNSIGNED:
+        unsigned_char = 1;
+    case EXT2_HTREE_LEGACY:
+        major = ext2_legacy_hash(name, len, unsigned_char);
+        break;
+    case EXT2_HTREE_HALF_MD4_UNSIGNED:
+        unsigned_char = 1;
+    case EXT2_HTREE_HALF_MD4:
+        while (len > 0) {
+            ext2_prep_hashbuf(name, len, data, 32, unsigned_char);
+            ext2_half_md4(hash, data);
+            len -= 32;
+            name += 32;
+        }
+        major = hash[0];
+        minor = hash[1];
+        break;
+    default:
+        goto error;
+    }
+
+    major &= ~1;
+    if (major == (EXT2_HTREE_EOF << 1))
+        major = (EXT2_HTREE_EOF - 1) << 1;
+    *hash_major = major;
+    if (hash_minor)
+        *hash_minor = minor;
+
+    return EOK;
+
+    error:
+    *hash_major = 0;
+    if (hash_minor)
+        *hash_minor = 0;
+    return ENOTSUP;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_hash.h
@@ -1,0 +1,61 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ * 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_hash.h
+ * @brief Directory indexing hash functions.
+ */
+
+#ifndef EXT4_HASH_H_
+#define EXT4_HASH_H_
+
+#include <ext4_config.h>
+
+#include <stdint.h>
+
+/**@brief	Directory entry name hash function.
+ * @param	name entry name
+ * @param	len entry name length
+ * @param	hash_seed (from superblock)
+ * @param	hash version (from superblock)
+ * @param	hash_minor output value
+ * @param	hash_major output value
+ * @return 	standard error code*/
+int ext2_htree_hash(const char *name, int len,
+        const uint32_t *hash_seed, int hash_version,
+        uint32_t *hash_major, uint32_t *hash_minor);
+
+
+#endif /* EXT4_HASH_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_ialloc.c
@@ -1,0 +1,250 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_ialloc.c
+ * @brief Inode allocation procedures.
+ */
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <ext4_ialloc.h>
+#include <ext4_super.h>
+#include <ext4_fs.h>
+#include <ext4_blockdev.h>
+#include <ext4_block_group.h>
+#include <ext4_bitmap.h>
+
+static uint32_t ext4_ialloc_inode2index_in_group(struct ext4_sblock *sb,
+    uint32_t inode)
+{
+    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+    return (inode - 1) % inodes_per_group;
+}
+
+static uint32_t ext4_ialloc_index_in_group2inode(struct ext4_sblock *sb,
+        uint32_t index, uint32_t bgid)
+{
+    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+    return bgid * inodes_per_group + (index + 1);
+}
+
+static uint32_t ext4_ialloc_get_bgid_of_inode(struct ext4_sblock *sb,
+        uint32_t inode)
+{
+    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
+    return (inode - 1) / inodes_per_group;
+}
+
+
+int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir)
+{
+    struct ext4_sblock *sb = &fs->sb;
+
+    /* Compute index of block group and load it */
+    uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);
+
+    struct ext4_block_group_ref bg_ref;
+    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    /* Load i-node bitmap */
+    uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(
+            bg_ref.block_group, sb);
+
+    struct	ext4_block bitmap_block;
+    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+    if (rc != EOK)
+        return rc;
+
+    /* Free i-node in the bitmap */
+    uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
+    ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
+    bitmap_block.dirty = true;
+
+    /* Put back the block with bitmap */
+    rc = ext4_block_set(fs->bdev, &bitmap_block);
+    if (rc != EOK) {
+        /* Error in saving bitmap */
+        ext4_fs_put_block_group_ref(&bg_ref);
+        return rc;
+    }
+
+    /* If released i-node is a directory, decrement used directories count */
+    if (is_dir) {
+        uint32_t bg_used_dirs = ext4_bg_get_used_dirs_count(
+                bg_ref.block_group, sb);
+        bg_used_dirs--;
+        ext4_bg_set_used_dirs_count(bg_ref.block_group, sb,
+                bg_used_dirs);
+    }
+
+    /* Update block group free inodes count */
+    uint32_t free_inodes = ext4_bg_get_free_inodes_count(
+            bg_ref.block_group, sb);
+    free_inodes++;
+    ext4_bg_set_free_inodes_count(bg_ref.block_group, sb,
+            free_inodes);
+
+    bg_ref.dirty = true;
+
+    /* Put back the modified block group */
+    rc = ext4_fs_put_block_group_ref(&bg_ref);
+    if (rc != EOK)
+        return rc;
+
+    /* Update superblock free inodes count */
+    ext4_set32(sb, free_inodes_count, ext4_get32(sb, free_inodes_count) + 1);
+
+    return EOK;
+}
+
+int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir)
+{
+    struct ext4_sblock *sb = &fs->sb;
+
+    uint32_t bgid = 0;
+    uint32_t bg_count = ext4_block_group_cnt(sb);
+    uint32_t sb_free_inodes = ext4_get32(sb, free_inodes_count);
+    uint32_t avg_free_inodes = sb_free_inodes / bg_count;
+
+    /* Try to find free i-node in all block groups */
+    while (bgid < bg_count) {
+        /* Load block group to check */
+        struct ext4_block_group_ref bg_ref;
+        int rc = ext4_fs_get_block_group_ref(fs, bgid, &bg_ref);
+        if (rc != EOK)
+            return rc;
+
+        struct ext4_bgroup *bg = bg_ref.block_group;
+
+        /* Read necessary values for algorithm */
+        uint32_t free_blocks = ext4_bg_get_free_blocks_count(bg, sb);
+        uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);
+        uint32_t used_dirs = ext4_bg_get_used_dirs_count(bg, sb);
+
+        /* Check if this block group is good candidate for allocation */
+        if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) {
+            /* Load block with bitmap */
+            uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(
+                    bg_ref.block_group, sb);
+
+            struct	ext4_block bitmap_block;
+            rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+            if (rc != EOK)
+                return rc;
+
+            /* Try to allocate i-node in the bitmap */
+            uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bgid);
+            uint32_t index_in_group;
+
+            rc = ext4_bmap_bit_find_clr(bitmap_block.data, 0, inodes_in_group,
+                    &index_in_group);
+            /* Block group has not any free i-node */
+            if (rc == ENOSPC) {
+                ext4_block_set(fs->bdev, &bitmap_block);
+                ext4_fs_put_block_group_ref(&bg_ref);
+                continue;
+            }
+
+            ext4_bmap_bit_set(bitmap_block.data, index_in_group);
+
+            /* Free i-node found, save the bitmap */
+            bitmap_block.dirty = true;
+
+            ext4_block_set(fs->bdev, &bitmap_block);
+            if (rc != EOK)
+                return rc;
+
+            /* Modify filesystem counters */
+            free_inodes--;
+            ext4_bg_set_free_inodes_count(bg, sb, free_inodes);
+
+            /* Increment used directories counter */
+            if (is_dir) {
+                used_dirs++;
+                ext4_bg_set_used_dirs_count(bg, sb, used_dirs);
+            }
+
+            /* Decrease unused inodes count */
+            if (ext4_bg_has_flag(bg,
+                    EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
+                uint32_t unused =
+                        ext4_bg_get_itable_unused(bg, sb);
+
+                uint32_t inodes_in_group =
+                        ext4_inodes_in_group_cnt(sb, bgid);
+
+                uint32_t free = inodes_in_group - unused;
+
+                if (index_in_group >= free) {
+                    unused = inodes_in_group - (index_in_group + 1);
+                    ext4_bg_set_itable_unused(bg, sb, unused);
+                }
+            }
+
+            /* Save modified block group */
+            bg_ref.dirty = true;
+
+            rc = ext4_fs_put_block_group_ref(&bg_ref);
+            if (rc != EOK)
+                return rc;
+
+            /* Update superblock */
+            sb_free_inodes--;
+            ext4_set32(sb, free_inodes_count, sb_free_inodes);
+
+
+            /* Compute the absolute i-nodex number */
+            *index = ext4_ialloc_index_in_group2inode(sb,
+                    index_in_group, bgid);
+
+            return EOK;
+        }
+
+        /* Block group not modified, put it and jump to the next block group */
+        ext4_fs_put_block_group_ref(&bg_ref);
+        ++bgid;
+    }
+
+    return ENOSPC;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_ialloc.h
@@ -1,0 +1,63 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_ialloc.c
+ * @brief Inode allocation procedures.
+ */
+
+#ifndef EXT4_IALLOC_H_
+#define EXT4_IALLOC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+
+
+int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir);
+int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* EXT4_IALLOC_H_ */
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_inode.c
@@ -1,0 +1,353 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_inode.c
+ * @brief Inode handle functions
+ */
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+#include <ext4_inode.h>
+#include <ext4_super.h>
+
+static uint32_t ext4_inode_block_bits_count(uint32_t block_size)
+{
+    uint32_t bits = 8;
+    uint32_t size = block_size;
+
+    do {
+        bits++;
+        size = size >> 1;
+    } while (size > 256);
+
+    return bits;
+}
+
+
+uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+    uint32_t v = to_le16(inode->mode);
+
+    if(ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD){
+        v |= ((uint32_t) to_le16(inode->osd2.hurd2.mode_high)) << 16;
+    }
+
+    return v;
+}
+
+void 	 ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
+    uint32_t mode)
+{
+    inode->mode = to_le16((mode << 16) >> 16);
+
+    if(ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)
+        inode->osd2.hurd2.mode_high = to_le16(mode >> 16);
+}
+
+
+
+uint32_t ext4_inode_get_uid(struct ext4_inode *inode)
+{
+    return to_le32(inode->uid);
+}
+
+void 	 ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid)
+{
+    inode->uid = to_le32(uid);
+}
+
+
+uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+    uint64_t v = to_le32(inode->size_lo);
+
+    if ((ext4_get32(sb, rev_level) > 0) && (ext4_inode_is_type(sb, inode,
+            EXT4_INODE_MODE_FILE)))
+        v |= ((uint64_t)to_le32(inode->size_hi)) << 32;
+
+    return v;
+}
+
+void 	 ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)
+{
+    inode->size_lo = to_le32((size << 32) >> 32);
+    inode->size_hi = to_le32(size >> 32);
+}
+
+
+uint32_t ext4_inode_get_access_time(struct ext4_inode *inode)
+{
+    return to_le32(inode->access_time);
+}
+void 	 ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time)
+{
+    inode->access_time = to_le32(time);
+}
+
+
+uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode)
+{
+    return to_le32(inode->change_inode_time);
+}
+void 	 ext4_inode_set_change_inode_time(struct ext4_inode *inode,
+    uint32_t time)
+{
+    inode->change_inode_time = to_le32(time);
+}
+
+
+uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode)
+{
+    return to_le32(inode->modification_time);
+}
+
+void 	 ext4_inode_set_modification_time(struct ext4_inode *inode,
+    uint32_t time)
+{
+    inode->modification_time = to_le32(time);
+}
+
+
+uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode)
+{
+    return to_le32(inode->deletion_time);
+}
+
+void 	 ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time)
+{
+    inode->deletion_time = to_le32(time);
+}
+
+uint32_t ext4_inode_get_gid(struct ext4_inode *inode)
+{
+    return to_le32(inode->gid);
+}
+void 	 ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid)
+{
+    inode->gid	= to_le32(gid);
+}
+
+uint16_t ext4_inode_get_links_count(struct ext4_inode *inode)
+{
+    return to_le16(inode->links_count);
+}
+void 	 ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt)
+{
+    inode->links_count = to_le16(cnt);
+}
+
+
+uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
+    struct ext4_inode *inode)
+{
+    uint64_t count = to_le32(inode->blocks_count_lo);
+
+    if (ext4_sb_check_read_only(sb,
+            EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+
+        /* 48-bit field */
+        count = ((uint64_t) to_le16(inode->osd2.linux2.blocks_high)) << 32;
+
+        if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {
+
+            uint32_t block_bits =
+                    ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
+            return count << (block_bits - 9);
+        } else
+            return count;
+    }
+
+    return count;
+}
+
+
+int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
+    struct ext4_inode *inode, uint64_t count)
+{
+    /* 32-bit maximum */
+    uint64_t max = 0;
+    max = ~max >> 32;
+
+    if (count <= max) {
+        inode->blocks_count_lo = to_le32(count);
+        inode->osd2.linux2.blocks_high = 0;
+        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+
+        return EOK;
+    }
+
+    /* Check if there can be used huge files (many blocks) */
+    if (!ext4_sb_check_read_only(sb,
+            EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
+        return EINVAL;
+
+    /* 48-bit maximum */
+    max = 0;
+    max = ~max >> 16;
+
+    if (count <= max) {
+        inode->blocks_count_lo = to_le32(count);
+        inode->osd2.linux2.blocks_high = to_le16(count >> 32);
+        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+    } else {
+        uint32_t block_bits = ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
+
+        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+        count = count >> (block_bits - 9);
+        inode->blocks_count_lo = to_le32(count);
+        inode->osd2.linux2.blocks_high = to_le16(count >> 32);
+    }
+
+    return EOK;
+}
+
+
+uint32_t ext4_inode_get_flags(struct ext4_inode *inode)
+{
+    return to_le32(inode->flags);
+}
+void 	 ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags)
+{
+    inode->flags = 	to_le32(flags);
+}
+
+uint32_t ext4_inode_get_generation(struct ext4_inode *inode)
+{
+    return to_le32(inode->generation);
+}
+void 	 ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen)
+{
+    inode->generation = to_le32(gen);
+}
+
+uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
+    struct ext4_sblock *sb)
+{
+    /*TODO: Verify it*/
+    uint64_t v = to_le32(inode->file_acl_lo);
+
+    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
+        v |= ((uint32_t) to_le16(inode->osd2.linux2.file_acl_high)) << 16;
+
+
+    return v;
+}
+
+void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,
+    uint64_t acl)
+{
+    /*TODO: Verify it*/
+    inode->file_acl_lo = to_le32((acl << 32) >> 32);
+
+    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
+        inode->osd2.linux2.file_acl_high = to_le16(acl >> 32);
+}
+
+
+
+uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx)
+{
+    return to_le32(inode->blocks[idx]);
+}
+void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
+    uint32_t block)
+{
+    inode->blocks[idx] = to_le32(block);
+}
+
+
+uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx)
+{
+    return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);
+}
+
+void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
+    uint32_t block)
+{
+    inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);
+}
+
+bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
+    uint32_t type)
+{
+    return (ext4_inode_get_mode(sb, inode) &
+            EXT4_INODE_MODE_TYPE_MASK) == type;
+}
+
+bool 	 ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f)
+{
+    return ext4_inode_get_flags(inode) & f;
+}
+
+void 	 ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f)
+{
+    uint32_t flags = ext4_inode_get_flags(inode);
+    flags = flags & (~f);
+    ext4_inode_set_flags(inode, flags);
+}
+
+void 	 ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f)
+{
+    uint32_t flags = ext4_inode_get_flags(inode);
+    flags = flags | f;
+    ext4_inode_set_flags(inode, flags);
+}
+
+bool 	 ext4_inode_can_truncate(struct ext4_sblock *sb,
+    struct ext4_inode *inode)
+{
+    if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||
+            (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))
+        return false;
+
+    if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||
+            (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)))
+        return true;
+
+    return false;
+}
+
+
+struct ext4_extent_header * ext4_inode_get_extent_header(
+    struct ext4_inode *inode)
+{
+    return (struct ext4_extent_header *) inode->blocks;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_inode.h
@@ -1,0 +1,129 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_inode.h
+ * @brief Inode handle functions
+ */
+
+#ifndef EXT4_INODE_H_
+#define EXT4_INODE_H_
+
+#include <ext4_config.h>
+#include <stdint.h>
+
+uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode);
+void ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
+    uint32_t mode);
+
+
+uint32_t ext4_inode_get_uid(struct ext4_inode *inode);
+void 	 ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid);
+
+
+uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode);
+void ext4_inode_set_size(struct ext4_inode *inode, uint64_t size);
+
+
+uint32_t ext4_inode_get_access_time(struct ext4_inode *inode);
+void 	 ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time);
+
+
+uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode);
+void ext4_inode_set_change_inode_time(struct ext4_inode *inode,
+    uint32_t time);
+
+
+uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode);
+void ext4_inode_set_modification_time(struct ext4_inode *inode, uint32_t time);
+
+
+uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode);
+void ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time);
+
+uint32_t ext4_inode_get_gid(struct ext4_inode *inode);
+void 	 ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid);
+
+uint16_t ext4_inode_get_links_count(struct ext4_inode *inode);
+void ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt);
+
+
+uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
+    struct ext4_inode *inode);
+int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
+    struct ext4_inode *inode, uint64_t cnt);
+
+
+uint32_t ext4_inode_get_flags(struct ext4_inode *inode);
+void ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags);
+
+uint32_t ext4_inode_get_generation(struct ext4_inode *inode);
+void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen);
+
+uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
+    struct ext4_sblock *sb);
+void ext4_inode_set_file_acl(struct ext4_inode *inode,
+    struct ext4_sblock *sb, uint64_t acl);
+
+
+uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx);
+void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
+    uint32_t block);
+
+
+uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx);
+void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
+    uint32_t block);
+
+bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
+    uint32_t type);
+
+
+bool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f);
+void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f);
+void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f);
+
+bool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode);
+
+
+struct ext4_extent_header * ext4_inode_get_extent_header(struct ext4_inode *inode);
+
+#endif /* EXT4_INODE_H_ */
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_super.c
@@ -1,0 +1,133 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_super.h
+ * @brief Superblock operations.
+ */
+
+#include <ext4_config.h>
+#include <ext4_super.h>
+
+
+uint32_t ext4_block_group_cnt(struct ext4_sblock *s)
+{
+    uint64_t blocks_count = ext4_sb_get_blocks_cnt(s);
+    uint32_t blocks_per_group = ext4_get32(s, blocks_per_group);
+
+    uint32_t block_groups_count = blocks_count / blocks_per_group;
+
+    if (blocks_count % blocks_per_group)
+        block_groups_count++;
+
+    return block_groups_count;
+}
+
+uint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid)
+{
+    uint32_t block_group_count = ext4_block_group_cnt(s);
+    uint32_t blocks_per_group  = ext4_get32(s, blocks_per_group);
+    uint64_t total_blocks 	   = ext4_sb_get_blocks_cnt(s);
+
+    if (bgid < block_group_count - 1)
+        return blocks_per_group;
+
+
+    return (total_blocks - ((block_group_count - 1) * blocks_per_group));
+}
+
+uint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid)
+{
+    uint32_t block_group_count = ext4_block_group_cnt(s);
+    uint32_t inodes_per_group  = ext4_get32(s, inodes_per_group);
+    uint32_t total_inodes =		 ext4_get32(s, inodes_count);
+
+
+    if (bgid < block_group_count - 1)
+        return inodes_per_group;
+
+    return (total_inodes - ((block_group_count - 1) * inodes_per_group));
+}
+
+int	ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s)
+{
+    return ext4_block_writebytes(bdev, EXT4_SUPERBLOCK_OFFSET,
+            s, EXT4_SUPERBLOCK_SIZE);
+}
+
+int	ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s)
+{
+    return ext4_block_readbytes(bdev, EXT4_SUPERBLOCK_OFFSET,
+            s, EXT4_SUPERBLOCK_SIZE);
+}
+
+bool ext4_sb_check(struct ext4_sblock *s)
+{
+    if (ext4_get16(s, magic) != EXT4_SUPERBLOCK_MAGIC)
+        return false;
+
+    if (ext4_get32(s, inodes_count) == 0)
+        return false;
+
+    if (ext4_sb_get_blocks_cnt(s) == 0)
+        return false;
+
+    if (ext4_get32(s, blocks_per_group) == 0)
+        return false;
+
+    if (ext4_get32(s, inodes_per_group) == 0)
+        return false;
+
+    if (ext4_get16(s, inode_size) < 128)
+        return false;
+
+    if (ext4_get32(s, first_inode) < 11)
+        return false;
+
+    if (ext4_sb_get_desc_size(s) <
+            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        return false;
+
+    if (ext4_sb_get_desc_size(s)  >
+    EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)
+        return false;
+
+    return true;
+}
+
+/**
+ * @}
+ */
--- /dev/null
+++ b/lwext4/ext4_super.h
@@ -1,0 +1,187 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_super.c
+ * @brief Superblock operations.
+ */
+
+#ifndef EXT4_SUPER_H_
+#define EXT4_SUPER_H_
+
+
+#include <ext4_config.h>
+#include <ext4_types.h>
+
+
+/****************************Unstandard access to superblock*****************/
+
+/**@brief	Blocks count get stored in superblock.
+ * @param	s superblock descriptor
+ * @return	count of blocks*/
+static inline uint64_t 	ext4_sb_get_blocks_cnt(struct ext4_sblock *s)
+{
+    return ((uint64_t) to_le32(s->blocks_count_hi) << 32) |
+            to_le32(s->blocks_count_lo);
+}
+
+/**@brief	Free blocks count get stored in superblock.
+ * @param	s superblock descriptor
+ * @return	free blocks*/
+static inline uint64_t 	ext4_sb_get_free_blocks_cnt(struct ext4_sblock *s)
+{
+    return ((uint64_t) to_le32(s->free_blocks_count_hi) << 32) |
+            to_le32(s->free_blocks_count_lo);
+}
+
+/**@brief	Free blocks count set.
+ * @param	s superblock descriptor
+ * @param	cnt new value of free blocks*/
+static inline void 	ext4_sb_set_free_blocks_cnt(struct ext4_sblock *s,
+    uint64_t cnt)
+{
+    s->free_blocks_count_lo = to_le32((cnt << 32) >> 32);
+    s->free_blocks_count_hi = to_le32(cnt >> 32);
+}
+
+/**@brief	Block size get from superblock.
+ * @param	s superblock descriptor
+ * @return	block size in bytes*/
+static inline uint32_t 	ext4_sb_get_block_size(struct ext4_sblock *s)
+{
+    return 1024 << to_le32(s->log_block_size);
+}
+
+/**@brief	Block group descriptor size.
+ * @param	s superblock descriptor
+ * @return	block group descriptor size in bytes*/
+static inline uint16_t ext4_sb_get_desc_size(struct ext4_sblock *s)
+{
+    uint16_t size = to_le16(s->desc_size);
+
+    return size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE ?
+            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE : size;
+}
+
+/*************************Flags and features*********************************/
+
+/**@brief	Support check of flag.
+ * @param	s superblock descriptor
+ * @param	v flag to check
+ * @return	true if flag is supported*/
+static inline bool ext4_sb_check_flag(struct ext4_sblock *s, uint32_t v)
+{
+    return to_le32(s->flags) & v;
+}
+
+/**@brief	Support check of feature compatible.
+ * @param	s superblock descriptor
+ * @param	v feature to check
+ * @return	true if feature is supported*/
+static inline bool ext4_sb_check_feature_compatible(struct ext4_sblock *s,
+    uint32_t v)
+{
+    return to_le32(s->features_compatible) & v;
+}
+
+
+/**@brief	Support check of feature incompatible.
+ * @param	s superblock descriptor
+ * @param	v feature to check
+ * @return	true if feature is supported*/
+static inline bool ext4_sb_check_feature_incompatible(struct ext4_sblock *s,
+    uint32_t v)
+{
+    return to_le32(s->features_incompatible) & v;
+}
+
+
+/**@brief	Support check of read only flag.
+ * @param	s superblock descriptor
+ * @param	v flag to check
+ * @return	true if flag is supported*/
+static inline bool ext4_sb_check_read_only(struct ext4_sblock *s, uint32_t v)
+{
+    return to_le32(s->features_read_only) & v;
+}
+
+/**************************More complex functions****************************/
+
+/**@brief	Returns a block group count.
+ * @param	s superblock descriptor
+ * @return	count of block groups*/
+uint32_t ext4_block_group_cnt(struct ext4_sblock *s);
+
+/**@brief	Returns block count in block group
+ *          (last block group may have less blocks)
+ * @param	s superblock descriptor
+ * @param	bgid block group id
+ * @return	blocks count*/
+uint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid);
+
+/**@brief	Returns inodes count in block group
+ *          (last block group may have less inodes)
+ * @param	s superblock descriptor
+ * @param	bgid block group id
+ * @return	inodes count*/
+uint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid);
+
+/***************************Read/write/check superblock**********************/
+
+/**@brief	Superblock write.
+ * @param	bdev block device descriptor.
+ * @param	s superblock descruptor
+ * @return 	Standard error code */
+int	ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s);
+
+/**@brief	Superblock read.
+ * @param	bdev block device descriptor.
+ * @param	s superblock descruptor
+ * @return 	Standard error code */
+int	ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s);
+
+/**@brief	Superblock simple validation.
+ * @param	s superblock dsecriptor
+ * @return	true if OK*/
+bool ext4_sb_check(struct ext4_sblock *s);
+
+
+#endif /* EXT4_SUPER_H_ */
+
+/**
+ * @}
+ */
+
--- /dev/null
+++ b/lwext4/ext4_types.h
@@ -1,0 +1,613 @@
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 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 lwext4
+ * @{
+ */
+/**
+ * @file  ext4_types.h
+ * @brief Ext4 data structure definitions.
+ */
+
+#ifndef EXT4_TYPES_H_
+#define EXT4_TYPES_H_
+
+#include <ext4_config.h>
+#include <ext4_blockdev.h>
+
+#include <stdint.h>
+
+
+/*
+ * Structure of the super block
+ */
+struct ext4_sblock {
+    uint32_t inodes_count;              /* I-nodes count */
+    uint32_t blocks_count_lo;           /* Blocks count */
+    uint32_t reserved_blocks_count_lo;  /* Reserved blocks count */
+    uint32_t free_blocks_count_lo;      /* Free blocks count */
+    uint32_t free_inodes_count;         /* Free inodes count */
+    uint32_t first_data_block;          /* First Data Block */
+    uint32_t log_block_size;            /* Block size */
+    uint32_t log_frag_size;             /* Obsoleted fragment size */
+    uint32_t blocks_per_group;          /* Number of blocks per group */
+    uint32_t frags_per_group;           /* Obsoleted fragments per group */
+    uint32_t inodes_per_group;          /* Number of inodes per group */
+    uint32_t mount_time;                /* Mount time */
+    uint32_t write_time;                /* Write time */
+    uint16_t mount_count;               /* Mount count */
+    uint16_t max_mount_count;           /* Maximal mount count */
+    uint16_t magic;                     /* Magic signature */
+    uint16_t state;                     /* File system state */
+    uint16_t errors;                    /* Behaviour when detecting errors */
+    uint16_t minor_rev_level;           /* Minor revision level */
+    uint32_t last_check_time;           /* Time of last check */
+    uint32_t check_interval;            /* Maximum time between checks */
+    uint32_t creator_os;                /* Creator OS */
+    uint32_t rev_level;                 /* Revision level */
+    uint16_t def_resuid;                /* Default uid for reserved blocks */
+    uint16_t def_resgid;                /* Default gid for reserved blocks */
+
+    /* Fields for EXT4_DYNAMIC_REV superblocks only. */
+    uint32_t first_inode;             /* First non-reserved inode */
+    uint16_t inode_size;              /* Size of inode structure */
+    uint16_t block_group_index;       /* Block group index of this superblock */
+    uint32_t features_compatible;     /* Compatible feature set */
+    uint32_t features_incompatible;   /* Incompatible feature set */
+    uint32_t features_read_only;      /* Readonly-compatible feature set */
+    uint8_t uuid[16];                 /* 128-bit uuid for volume */
+    char volume_name[16];             /* Volume name */
+    char last_mounted[64];            /* Directory where last mounted */
+    uint32_t algorithm_usage_bitmap;  /* For compression */
+
+    /*
+     * Performance hints. Directory preallocation should only
+     * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
+     */
+    uint8_t s_prealloc_blocks;       /* Number of blocks to try to preallocate */
+    uint8_t s_prealloc_dir_blocks;   /* Number to preallocate for dirs */
+    uint16_t s_reserved_gdt_blocks;  /* Per group desc for online growth */
+
+    /*
+     * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
+     */
+    uint8_t journal_uuid[16];       /* UUID of journal superblock */
+    uint32_t journal_inode_number;  /* Inode number of journal file */
+    uint32_t journal_dev;           /* Device number of journal file */
+    uint32_t last_orphan;           /* Head of list of inodes to delete */
+    uint32_t hash_seed[4];          /* HTREE hash seed */
+    uint8_t default_hash_version;   /* Default hash version to use */
+    uint8_t journal_backup_type;
+    uint16_t desc_size;             /* Size of group descriptor */
+    uint32_t default_mount_opts;    /* Default mount options */
+    uint32_t first_meta_bg;         /* First metablock block group */
+    uint32_t mkfs_time;             /* When the filesystem was created */
+    uint32_t journal_blocks[17];    /* Backup of the journal inode */
+
+    /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
+    uint32_t blocks_count_hi;           /* Blocks count */
+    uint32_t reserved_blocks_count_hi;  /* Reserved blocks count */
+    uint32_t free_blocks_count_hi;      /* Free blocks count */
+    uint16_t min_extra_isize;           /* All inodes have at least # bytes */
+    uint16_t want_extra_isize;          /* New inodes should reserve # bytes */
+    uint32_t flags;                     /* Miscellaneous flags */
+    uint16_t raid_stride;               /* RAID stride */
+    uint16_t mmp_interval;              /* # seconds to wait in MMP checking */
+    uint64_t mmp_block;                 /* Block for multi-mount protection */
+    uint32_t raid_stripe_width;         /* Blocks on all data disks (N * stride) */
+    uint8_t log_groups_per_flex;        /* FLEX_BG group size */
+    uint8_t reserved_char_pad;
+    uint16_t reserved_pad;
+    uint64_t kbytes_written;            /* Number of lifetime kilobytes written */
+    uint32_t snapshot_inum;             /* I-node number of active snapshot */
+    uint32_t snapshot_id;               /* Sequential ID of active snapshot */
+    uint64_t snapshot_r_blocks_count;   /* Reserved blocks for active snapshot's future use */
+    uint32_t snapshot_list;             /* I-node number of the head of the on-disk snapshot list */
+    uint32_t error_count;               /* Number of file system errors */
+    uint32_t first_error_time;          /* First time an error happened */
+    uint32_t first_error_ino;           /* I-node involved in first error */
+    uint64_t first_error_block;         /* Block involved of first error */
+    uint8_t first_error_func[32];       /* Function where the error happened */
+    uint32_t first_error_line;          /* Line number where error happened */
+    uint32_t last_error_time;           /* Most recent time of an error */
+    uint32_t last_error_ino;            /* I-node involved in last error */
+    uint32_t last_error_line;           /* Line number where error happened */
+    uint64_t last_error_block;          /* Block involved of last error */
+    uint8_t last_error_func[32];        /* Function where the error happened */
+    uint8_t mount_opts[64];
+    uint32_t padding[112];              /* Padding to the end of the block */
+} __attribute__((packed));
+
+
+#define EXT4_SUPERBLOCK_MAGIC   0xEF53
+#define EXT4_SUPERBLOCK_SIZE    1024
+#define EXT4_SUPERBLOCK_OFFSET  1024
+
+#define EXT4_SUPERBLOCK_OS_LINUX  0
+#define EXT4_SUPERBLOCK_OS_HURD   1
+
+/*
+ * Misc. filesystem flags
+ */
+#define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH    0x0001  /* Signed dirhash in use */
+#define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH  0x0002  /* Unsigned dirhash in use */
+#define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS   0x0004  /* to test development code */
+
+/*
+ * Filesystem states
+ */
+#define EXT4_SUPERBLOCK_STATE_VALID_FS   0x0001  /* Unmounted cleanly */
+#define EXT4_SUPERBLOCK_STATE_ERROR_FS   0x0002  /* Errors detected */
+#define EXT4_SUPERBLOCK_STATE_ORPHAN_FS  0x0004  /* Orphans being recovered */
+
+/*
+ * Behaviour when errors detected
+ */
+#define EXT4_SUPERBLOCK_ERRORS_CONTINUE  1  /* Continue execution */
+#define EXT4_SUPERBLOCK_ERRORS_RO        2  /* Remount fs read-only */
+#define EXT4_SUPERBLOCK_ERRORS_PANIC     3  /* Panic */
+#define EXT4_SUPERBLOCK_ERRORS_DEFAULT   EXT4_ERRORS_CONTINUE
+
+/*
+ * Compatible features
+ */
+#define EXT4_FEATURE_COMPAT_DIR_PREALLOC   0x0001
+#define EXT4_FEATURE_COMPAT_IMAGIC_INODES  0x0002
+#define EXT4_FEATURE_COMPAT_HAS_JOURNAL    0x0004
+#define EXT4_FEATURE_COMPAT_EXT_ATTR       0x0008
+#define EXT4_FEATURE_COMPAT_RESIZE_INODE   0x0010
+#define EXT4_FEATURE_COMPAT_DIR_INDEX      0x0020
+
+/*
+ * Read-only compatible features
+ */
+#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER  0x0001
+#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE    0x0002
+#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR     0x0004
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE     0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM      0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK     0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE   0x0040
+
+/*
+ * Incompatible features
+ */
+#define EXT4_FEATURE_INCOMPAT_COMPRESSION  0x0001
+#define EXT4_FEATURE_INCOMPAT_FILETYPE     0x0002
+#define EXT4_FEATURE_INCOMPAT_RECOVER      0x0004  /* Needs recovery */
+#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV  0x0008  /* Journal device */
+#define EXT4_FEATURE_INCOMPAT_META_BG      0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS      0x0040  /* extents support */
+#define EXT4_FEATURE_INCOMPAT_64BIT        0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP          0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG      0x0200
+#define EXT4_FEATURE_INCOMPAT_EA_INODE     0x0400  /* EA in inode */
+#define EXT4_FEATURE_INCOMPAT_DIRDATA      0x1000  /* data in dirent */
+
+#define EXT4_FEATURE_COMPAT_SUPP  (EXT4_FEATURE_COMPAT_DIR_INDEX)
+
+#define EXT4_FEATURE_INCOMPAT_SUPP \
+        (EXT4_FEATURE_INCOMPAT_FILETYPE | \
+                EXT4_FEATURE_INCOMPAT_EXTENTS | \
+                EXT4_FEATURE_INCOMPAT_64BIT)
+
+#define EXT4_FEATURE_RO_COMPAT_SUPP \
+        (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
+                EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
+                EXT4_FEATURE_RO_COMPAT_HUGE_FILE | \
+                EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
+                EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \
+                EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
+
+struct ext4_fs {
+    struct ext4_blockdev	*bdev;
+    struct ext4_sblock  	sb;
+
+    uint64_t inode_block_limits[4];
+    uint64_t inode_blocks_per_level[4];
+};
+
+
+#define EXT4_BLOCK_GROUP_INODE_UNINIT   0x0001  /* Inode table/bitmap not in use */
+#define EXT4_BLOCK_GROUP_BLOCK_UNINIT   0x0002  /* Block bitmap not in use */
+#define EXT4_BLOCK_GROUP_ITABLE_ZEROED  0x0004  /* On-disk itable initialized to zero */
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext4_bgroup {
+    uint32_t block_bitmap_lo;             /* Blocks bitmap block */
+    uint32_t inode_bitmap_lo;             /* Inodes bitmap block */
+    uint32_t inode_table_first_block_lo;  /* Inodes table block */
+    uint16_t free_blocks_count_lo;        /* Free blocks count */
+    uint16_t free_inodes_count_lo;        /* Free inodes count */
+    uint16_t used_dirs_count_lo;          /* Directories count */
+    uint16_t flags;                       /* EXT4_BG_flags (INODE_UNINIT, etc) */
+    uint32_t reserved[2];                 /* Likely block/inode bitmap checksum */
+    uint16_t itable_unused_lo;            /* Unused inodes count */
+    uint16_t checksum;                    /* crc16(sb_uuid+group+desc) */
+
+    uint32_t block_bitmap_hi;             /* Blocks bitmap block MSB */
+    uint32_t inode_bitmap_hi;             /* I-nodes bitmap block MSB */
+    uint32_t inode_table_first_block_hi;  /* I-nodes table block MSB */
+    uint16_t free_blocks_count_hi;        /* Free blocks count MSB */
+    uint16_t free_inodes_count_hi;        /* Free i-nodes count MSB */
+    uint16_t used_dirs_count_hi;          /* Directories count MSB */
+    uint16_t itable_unused_hi;            /* Unused inodes count MSB */
+    uint32_t reserved2[3];                /* Padding */
+} ;
+
+struct ext4_block_group_ref {
+    struct ext4_block 	block;
+    struct ext4_bgroup 	*block_group;
+    struct ext4_fs  	*fs;
+    uint32_t 			index;
+    bool 				dirty;
+};
+
+#define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE  32
+#define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE  64
+
+#define EXT4_MIN_BLOCK_SIZE   1024   /* 1 KiB */
+#define EXT4_MAX_BLOCK_SIZE   65536  /* 64 KiB */
+#define EXT4_REV0_INODE_SIZE  128
+
+#define EXT4_INODE_BLOCK_SIZE  512
+
+#define EXT4_INODE_DIRECT_BLOCK_COUNT      12
+#define EXT4_INODE_INDIRECT_BLOCK          EXT4_INODE_DIRECT_BLOCK_COUNT
+#define EXT4_INODE_DOUBLE_INDIRECT_BLOCK   (EXT4_INODE_INDIRECT_BLOCK + 1)
+#define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK  (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
+#define EXT4_INODE_BLOCKS                  (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
+#define EXT4_INODE_INDIRECT_BLOCK_COUNT    (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext4_inode {
+    uint16_t mode;                       /* File mode */
+    uint16_t uid;                        /* Low 16 bits of owner uid */
+    uint32_t size_lo;                    /* Size in bytes */
+    uint32_t access_time;                /* Access time */
+    uint32_t change_inode_time;          /* I-node change time */
+    uint32_t modification_time;          /* Modification time */
+    uint32_t deletion_time;              /* Deletion time */
+    uint16_t gid;                        /* Low 16 bits of group id */
+    uint16_t links_count;                /* Links count */
+    uint32_t blocks_count_lo;            /* Blocks count */
+    uint32_t flags;                      /* File flags */
+    uint32_t unused_osd1;                /* OS dependent - not used in HelenOS */
+    uint32_t blocks[EXT4_INODE_BLOCKS];  /* Pointers to blocks */
+    uint32_t generation;                 /* File version (for NFS) */
+    uint32_t file_acl_lo;                /* File ACL */
+    uint32_t size_hi;
+    uint32_t obso_faddr;                 /* Obsoleted fragment address */
+
+    union {
+        struct {
+            uint16_t blocks_high;
+            uint16_t file_acl_high;
+            uint16_t uid_high;
+            uint16_t gid_high;
+            uint32_t reserved2;
+        } linux2;
+        struct {
+            uint16_t reserved1;
+            uint16_t mode_high;
+            uint16_t uid_high;
+            uint16_t gid_high;
+            uint32_t author;
+        } hurd2;
+    } __attribute__ ((packed)) osd2;
+
+    uint16_t extra_isize;
+    uint16_t pad1;
+    uint32_t ctime_extra;   /* Extra change time (nsec << 2 | epoch) */
+    uint32_t mtime_extra;   /* Extra Modification time (nsec << 2 | epoch) */
+    uint32_t atime_extra;   /* Extra Access time (nsec << 2 | epoch) */
+    uint32_t crtime;        /* File creation time */
+    uint32_t crtime_extra;  /* Extra file creation time (nsec << 2 | epoch) */
+    uint32_t version_hi;    /* High 32 bits for 64-bit version */
+} __attribute__ ((packed)) ;
+
+#define EXT4_INODE_MODE_FIFO       0x1000
+#define EXT4_INODE_MODE_CHARDEV    0x2000
+#define EXT4_INODE_MODE_DIRECTORY  0x4000
+#define EXT4_INODE_MODE_BLOCKDEV   0x6000
+#define EXT4_INODE_MODE_FILE       0x8000
+#define EXT4_INODE_MODE_SOFTLINK   0xA000
+#define EXT4_INODE_MODE_SOCKET     0xC000
+#define EXT4_INODE_MODE_TYPE_MASK  0xF000
+
+/*
+ * Inode flags
+ */
+#define EXT4_INODE_FLAG_SECRM      0x00000001  /* Secure deletion */
+#define EXT4_INODE_FLAG_UNRM       0x00000002  /* Undelete */
+#define EXT4_INODE_FLAG_COMPR      0x00000004  /* Compress file */
+#define EXT4_INODE_FLAG_SYNC       0x00000008  /* Synchronous updates */
+#define EXT4_INODE_FLAG_IMMUTABLE  0x00000010  /* Immutable file */
+#define EXT4_INODE_FLAG_APPEND     0x00000020  /* writes to file may only append */
+#define EXT4_INODE_FLAG_NODUMP     0x00000040  /* do not dump file */
+#define EXT4_INODE_FLAG_NOATIME    0x00000080  /* do not update atime */
+
+/* Compression flags */
+#define EXT4_INODE_FLAG_DIRTY     0x00000100
+#define EXT4_INODE_FLAG_COMPRBLK  0x00000200  /* One or more compressed clusters */
+#define EXT4_INODE_FLAG_NOCOMPR   0x00000400  /* Don't compress */
+#define EXT4_INODE_FLAG_ECOMPR    0x00000800  /* Compression error */
+
+#define EXT4_INODE_FLAG_INDEX         0x00001000  /* hash-indexed directory */
+#define EXT4_INODE_FLAG_IMAGIC        0x00002000  /* AFS directory */
+#define EXT4_INODE_FLAG_JOURNAL_DATA  0x00004000  /* File data should be journaled */
+#define EXT4_INODE_FLAG_NOTAIL        0x00008000  /* File tail should not be merged */
+#define EXT4_INODE_FLAG_DIRSYNC       0x00010000  /* Dirsync behaviour (directories only) */
+#define EXT4_INODE_FLAG_TOPDIR        0x00020000  /* Top of directory hierarchies */
+#define EXT4_INODE_FLAG_HUGE_FILE     0x00040000  /* Set to each huge file */
+#define EXT4_INODE_FLAG_EXTENTS       0x00080000  /* Inode uses extents */
+#define EXT4_INODE_FLAG_EA_INODE      0x00200000  /* Inode used for large EA */
+#define EXT4_INODE_FLAG_EOFBLOCKS     0x00400000  /* Blocks allocated beyond EOF */
+#define EXT4_INODE_FLAG_RESERVED      0x80000000  /* reserved for ext4 lib */
+
+#define EXT4_INODE_ROOT_INDEX  2
+
+struct ext4_inode_ref {
+    struct ext4_block 		 block;
+    struct ext4_inode 		*inode;
+    struct ext4_fs  *fs;
+    uint32_t index;
+    bool dirty;
+} ;
+
+
+#define EXT4_DIRECTORY_FILENAME_LEN  255
+
+#define EXT4_DIRECTORY_FILETYPE_UNKNOWN   0
+#define EXT4_DIRECTORY_FILETYPE_REG_FILE  1
+#define EXT4_DIRECTORY_FILETYPE_DIR       2
+#define EXT4_DIRECTORY_FILETYPE_CHRDEV    3
+#define EXT4_DIRECTORY_FILETYPE_BLKDEV    4
+#define EXT4_DIRECTORY_FILETYPE_FIFO      5
+#define EXT4_DIRECTORY_FILETYPE_SOCK      6
+#define EXT4_DIRECTORY_FILETYPE_SYMLINK   7
+
+/**
+ * Linked list directory entry structure
+ */
+struct ext4_directory_entry_ll {
+    uint32_t inode;         /* I-node for the entry */
+    uint16_t entry_length;  /* Distance to the next directory entry */
+    uint8_t name_length;    /* Lower 8 bits of name length */
+
+    union {
+        uint8_t name_length_high;  /* Higher 8 bits of name length */
+        uint8_t inode_type;        /* Type of referenced inode (in rev >= 0.5) */
+    } __attribute__ ((packed));
+
+    uint8_t name[EXT4_DIRECTORY_FILENAME_LEN];  /* Entry name */
+} __attribute__((packed)) ;
+
+struct ext4_directory_iterator {
+    struct ext4_inode_ref 			*inode_ref;
+    struct ext4_block 	   			current_block;
+    uint64_t 						current_offset;
+    struct ext4_directory_entry_ll  *current;
+};
+
+struct ext4_directory_search_result {
+    struct	ext4_block 		 		block;
+    struct  ext4_directory_entry_ll *dentry;
+};
+
+/* Structures for indexed directory */
+
+struct ext4_directory_dx_countlimit {
+    uint16_t limit;
+    uint16_t count;
+} ;
+
+struct ext4_directory_dx_dot_entry {
+    uint32_t inode;
+    uint16_t entry_length;
+    uint8_t name_length;
+    uint8_t inode_type;
+    uint8_t name[4];
+} ;
+
+struct ext4_directory_dx_root_info {
+    uint32_t reserved_zero;
+    uint8_t hash_version;
+    uint8_t info_length;
+    uint8_t indirect_levels;
+    uint8_t unused_flags;
+} ;
+
+struct ext4_directory_dx_entry {
+    uint32_t hash;
+    uint32_t block;
+} ;
+
+struct ext4_directory_dx_root {
+    struct ext4_directory_dx_dot_entry dots[2];
+    struct ext4_directory_dx_root_info info;
+    struct ext4_directory_dx_entry entries[0];
+};
+
+struct ext4_fake_directory_entry {
+    uint32_t inode;
+    uint16_t entry_length;
+    uint8_t name_length;
+    uint8_t inode_type;
+};
+
+struct ext4_directory_dx_node {
+    struct ext4_fake_directory_entry fake;
+    struct ext4_directory_dx_entry entries[0];
+};
+
+struct ext4_directory_dx_block {
+    struct ext4_block 		 	    block;
+    struct ext4_directory_dx_entry *entries;
+    struct ext4_directory_dx_entry *position;
+} ;
+
+#define EXT4_ERR_BAD_DX_DIR       (-75000)
+
+
+/*
+ * This is the extent on-disk structure.
+ * It's used at the bottom of the tree.
+ */
+struct ext4_extent {
+    uint32_t first_block;  /* First logical block extent covers */
+    uint16_t block_count;  /* Number of blocks covered by extent */
+    uint16_t start_hi;     /* High 16 bits of physical block */
+    uint32_t start_lo;     /* Low 32 bits of physical block */
+} ;
+
+/*
+ * This is index on-disk structure.
+ * It's used at all the levels except the bottom.
+ */
+struct ext4_extent_index {
+    uint32_t first_block;  /* Index covers logical blocks from 'block' */
+
+    /**
+     * Pointer to the physical block of the next
+     * level. leaf or next index could be there
+     * high 16 bits of physical block
+     */
+    uint32_t leaf_lo;
+    uint16_t leaf_hi;
+    uint16_t padding;
+} ;
+
+/*
+ * Each block (leaves and indexes), even inode-stored has header.
+ */
+struct ext4_extent_header {
+    uint16_t magic;
+    uint16_t entries_count;      /* Number of valid entries */
+    uint16_t max_entries_count;  /* Capacity of store in entries */
+    uint16_t depth;              /* Has tree real underlying blocks? */
+    uint32_t generation;         /* generation of the tree */
+} ;
+
+struct ext4_extent_path {
+    struct	ext4_block 		 	block;
+    uint16_t 					depth;
+    struct ext4_extent_header *header;
+    struct ext4_extent_index  *index;
+    struct ext4_extent 		  *extent;
+} ;
+
+#define EXT4_EXTENT_MAGIC  0xF30A
+
+#define	EXT4_EXTENT_FIRST(header) \
+        ((struct ext4_extent *) (((void *) (header)) + sizeof(struct ext4_extent_header)))
+
+#define	EXT4_EXTENT_FIRST_INDEX(header) \
+        ((struct ext4_extent_index *) (((void *) (header)) + sizeof(struct ext4_extent_header)))
+
+
+/* EXT3 HTree directory indexing */
+#define EXT2_HTREE_LEGACY					0
+#define EXT2_HTREE_HALF_MD4					1
+#define EXT2_HTREE_TEA						2
+#define EXT2_HTREE_LEGACY_UNSIGNED			3
+#define EXT2_HTREE_HALF_MD4_UNSIGNED		4
+#define EXT2_HTREE_TEA_UNSIGNED				5
+
+#define EXT2_HTREE_EOF 						0x7FFFFFFF
+
+
+struct ext4_hash_info {
+    uint32_t hash;
+    uint32_t minor_hash;
+    uint32_t hash_version;
+    const uint32_t *seed;
+};
+
+/*****************************************************************************/
+
+
+#ifdef CONFIG_BIG_ENDIAN
+static inline uint64_t to_le64(uint64_t n)
+{
+    return  ((n & 0xff) << 56) |
+            ((n & 0xff00) << 40) |
+            ((n & 0xff0000) << 24) |
+            ((n & 0xff000000LL) << 8) |
+            ((n & 0xff00000000LL) >> 8) |
+            ((n & 0xff0000000000LL) >> 24) |
+            ((n & 0xff000000000000LL) >> 40) |
+            ((n & 0xff00000000000000LL) >> 56);
+}
+
+static inline uint32_t to_le32(uint32_t n)
+{
+    return 	((n & 0xff) << 24) |
+            ((n & 0xff00) << 8) |
+            ((n & 0xff0000) >> 8) |
+            ((n & 0xff000000) >> 24);
+}
+
+static inline uint16_t to_le16(uint16_t n)
+{
+    return 	((n & 0xff) << 8) |
+            ((n & 0xff00) >> 8);
+}
+
+
+#else
+#define to_le64(_n)	_n
+#define to_le32(_n)	_n
+#define to_le16(_n)	_n
+#endif
+
+/****************************Access macros to ext4 structures*****************/
+
+#define ext4_get32(s, f)		to_le32((s)->f)
+#define ext4_get16(s, f)		to_le16((s)->f)
+#define ext4_get8(s, f)			(s)->f
+
+
+#define ext4_set32(s, f, v)		do { (s)->f = to_le32(v); }while(0)
+#define ext4_set16(s, f, v)		do { (s)->f = to_le16(v); }while(0)
+#define ext4_set8 (s, f, v)		do { (s)->f = (v); 		  }while(0)
+
+#endif /* EXT4_TYPES_H_ */
+
+/**
+ * @}
+ */
--- a/src/CMakeLists.txt
+++ /dev/null
@@ -1,46 +1,0 @@
-project(lwext4 C)
-cmake_minimum_required(VERSION 2.8)
-
-
-#LIBRARY
-include_directories(. lwext4)
-aux_source_directory(lwext4 LWEXT4_SRC)
-add_library(lwext4  ${LWEXT4_SRC})
-
-
-#EXECUTABLE
-
-if(CMAKE_SYSTEM_PROCESSOR STREQUAL  cortex-m3)
-#Library size print
-add_custom_target(size ALL DEPENDS lwext4 COMMAND ${SIZE} -B liblwext4.a)
-
-elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL  cortex-m4)
-#Library size print
-add_custom_target(size ALL DEPENDS lwext4 COMMAND ${SIZE} -B liblwext4.a)
-
-elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL  bf518)
-#Library size print
-add_custom_target(size ALL DEPENDS lwext4 COMMAND ${SIZE} -B liblwext4.a)
-
-else()
-#Generic example target
-include_directories(blockdev/filedev)
-aux_source_directory(blockdev/filedev FILEDEV_SRC)
-aux_source_directory(demos/generic GENERIC_SRC)
-add_executable(fileimage_demo ${GENERIC_SRC} ${FILEDEV_SRC})
-target_link_libraries(fileimage_demo lwext4)
-add_custom_target(size ALL DEPENDS lwext4 COMMAND size -B liblwext4.a)
-endif()
-
-#DISTRIBUTION
-set(CPACK_PACKAGE_VERSION_MAJOR "0")
-set(CPACK_PACKAGE_VERSION_MINOR "1")
-set(CPACK_PACKAGE_VERSION_PATCH "1")
-set(CPACK_SOURCE_GENERATOR "TBZ2")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME
-  "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
-set(CPACK_SOURCE_IGNORE_FILES
-"/build")
-include(CPack)
-
-add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
--- a/src/Makefile
+++ /dev/null
@@ -1,36 +1,0 @@
-
-all: generic bf518 cortex-m3 cortex-m4 generic
-
-bf518:
-	rm -R -f build_bf518
-	mkdir build_bf518
-	cd build_bf518 && cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchain/bf518.cmake ..
-	cd build_bf518 && make
-
-cortex-m3:
-	rm -R -f build_cortex-m3
-	mkdir build_cortex-m3
-	cd build_cortex-m3 && cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchain/cortex-m3.cmake ..
-	cd build_cortex-m3 && make
-
-cortex-m4:
-	rm -R -f build_cortex-m4
-	mkdir build_cortex-m4
-	cd build_cortex-m4 && cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=../toolchain/cortex-m4.cmake ..
-	cd build_cortex-m4 && make
-	
-	
-generic:
-	rm -R -f build_generic
-	mkdir build_generic
-	cd build_generic && cmake -G"Unix Makefiles" ../
-	cd build_generic && make
-	
-	
-clean:
-	rm -R -f build_bf518
-	rm -R -f build_cortex-m3
-	rm -R -f build_cortex-m4
-	rm -R -f build_generic
-
-	
\ No newline at end of file
--- a/src/blockdev/filedev/ext4_filedev.c
+++ /dev/null
@@ -1,135 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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.
- */
-#include <ext4_config.h>
-#include <ext4_blockdev.h>
-#include <ext4_errno.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-
-/**@brief	Default filename.*/
-const char *fname = "ext2";
-
-/**@brief	Image block size.*/
-#define EXT4_FILEDEV_BSIZE		512
-
-/**@brief	Image file descriptor.*/
-static FILE	*dev_file;
-
-
-/**********************BLOCKDEV INTERFACE**************************************/
-static int filedev_open(struct ext4_blockdev *bdev);
-static int filedev_bread(struct ext4_blockdev *bdev, void *buf, uint64_t blk_id,
-		uint32_t blk_cnt);
-static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf,
-		uint64_t blk_id, uint32_t blk_cnt);
-static int filedev_close(struct  ext4_blockdev *bdev);
-
-
-/******************************************************************************/
-EXT4_BLOCKDEV_STATIC_INSTANCE(
-		_filedev,
-		EXT4_FILEDEV_BSIZE,
-		0,
-		filedev_open,
-		filedev_bread,
-		filedev_bwrite,
-		filedev_close
-);
-
-/******************************************************************************/
-EXT4_BCACHE_STATIC_INSTANCE(__cache, 8, 1024);
-
-/******************************************************************************/
-static int filedev_open(struct ext4_blockdev *bdev)
-{
-	dev_file = fopen(fname, "r+b");
-
-	if(!dev_file)
-		return ENOENT;
-
-	if(fseek(dev_file, 0, SEEK_END))
-		return EFAULT;
-
-	_filedev.ph_bcnt = ftell(dev_file) / _filedev.ph_bsize;
-
-	return EOK;
-}
-
-/******************************************************************************/
-
-static int filedev_bread(struct  ext4_blockdev *bdev, void *buf, uint64_t blk_id,
-		uint32_t blk_cnt)
-{
-	if(fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET))
-		return EIO;
-
-	if(!fread(buf, bdev->ph_bsize * blk_cnt, 1, dev_file))
-		return EIO;
-
-	return EOK;
-}
-
-/******************************************************************************/
-static int filedev_bwrite(struct ext4_blockdev *bdev, const void *buf,
-		uint64_t blk_id, uint32_t blk_cnt)
-{
-	if(fseek(dev_file, blk_id * bdev->ph_bsize, SEEK_SET))
-		return EIO;
-
-	if(!fwrite(buf, bdev->ph_bsize * blk_cnt, 1, dev_file))
-		return EIO;
-	return EOK;
-}
-
-/******************************************************************************/
-static int filedev_close(struct  ext4_blockdev *bdev)
-{
-	fclose(dev_file);
-	return EOK;
-}
-
-
-/******************************************************************************/
-
-struct	ext4_bcache* ext4_filecache_get(void)
-{
-	return &__cache;
-}
-/******************************************************************************/
-struct	ext4_blockdev* ext4_filedev_get(void)
-{
-	return &_filedev;
-}
-/******************************************************************************/
-void ext4_filedev_filename(const char *n)
-{
-	fname = n;
-}
-
-/******************************************************************************/
--- a/src/blockdev/filedev/ext4_filedev.h
+++ /dev/null
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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.
- */
-#ifndef EXT4_FILEDEV_H_
-#define EXT4_FILEDEV_H_
-
-#include <ext4_config.h>
-#include <ext4_blockdev.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-
-/**@brief	Filecache get.*/
-struct	ext4_bcache*   ext4_filecache_get(void);
-
-/**@brief	File blockdev get.*/
-struct	ext4_blockdev* ext4_filedev_get(void);
-
-void 	ext4_filedev_filename(const char *n);
-
-#endif /* EXT4_FILEDEV_H_ */
--- a/src/demos/generic/main.c
+++ /dev/null
@@ -1,344 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <stdbool.h>
-
-#include <ext4_filedev.h>
-#include <ext4.h>
-
-
-
-char input_name[128] = "ext2";
-
-/**@brief	Read-write size*/
-static int rw_szie  = 1024;
-
-/**@brief	Read-write size*/
-static int rw_count = 1024;
-
-static bool cache_mode = false;
-
-
-/**@brief	File write buffer*/
-static uint8_t	*wr_buff;
-
-/**@brief	File read buffer.*/
-static uint8_t	*rd_buff;
-
-/**@brief	Block device handle.*/
-static struct ext4_blockdev *bd;
-
-/**@brief	Block cache handle.*/
-static struct ext4_bcache   *bc;
-
-static const char *usage = "									\n\
-Welcome in ext4 generic demo.									\n\
-Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)	\n\
-Usage:															\n\
-	-i   - input file            (default = ext2)				\n\
-	-rws - single R/W size       (default = 1024)				\n\
-	-rwc - R/W count             (default = 1024)				\n\
-	-cache - 0 static, 1 dynamic (default = 0)					\n\
-\n";
-
-static char* entry_to_str(uint8_t type)
-{
-	switch(type){
-	case EXT4_DIRENTRY_UNKNOWN:
-		return "[UNK] ";
-	case EXT4_DIRENTRY_REG_FILE:
-		return "[FIL] ";
-	case EXT4_DIRENTRY_DIR:
-		return "[DIR] ";
-	case EXT4_DIRENTRY_CHRDEV:
-		return "[CHA] ";
-	case EXT4_DIRENTRY_BLKDEV:
-		return "[BLK] ";
-	case EXT4_DIRENTRY_FIFO:
-		return "[FIF] ";
-	case EXT4_DIRENTRY_SOCK:
-		return "[SOC] ";
-	case EXT4_DIRENTRY_SYMLINK:
-		return "[SYM] ";
-	default:
-		break;
-	}
-	return "[???]";
-}
-
-static void dir_ls(const char *path)
-{
-	int j = 0;
-	char sss[255];
-	ext4_dir d;
-	ext4_direntry *de;
-
-	printf("**********************************************\n");
-
-	ext4_dir_open(&d, path);
-	de = ext4_entry_get(&d, j++);
-	printf("ls %s\n", path);
-
-	while(de){
-		memcpy(sss, de->name, de->name_length);
-		sss[de->name_length] = 0;
-		printf(entry_to_str(de->inode_type));
-		printf(sss);
-		printf("\n");
-		de = ext4_entry_get(&d, j++);
-	}
-	printf("**********************************************\n");
-	ext4_dir_close(&d);
-}
-
-static void mp_stats(void)
-{
-    struct ext4_mount_stats stats;
-    ext4_mount_point_stats("/mp/", &stats);
-
-    printf("**********************************************\n");
-    printf("ext4_mount_point_stats\n");
-    printf("inodes_count        = %d\n", stats.inodes_count);
-    printf("free_inodes_count   = %d\n", stats.free_inodes_count);
-    printf("blocks_count        = %d\n", stats.blocks_count);
-    printf("free_blocks_count   = %d\n", stats.free_blocks_count);
-    printf("block_size          = %d\n", stats.block_size);
-    printf("block_group_count   = %d\n", stats.block_group_count);
-    printf("blocks_per_group    = %d\n", stats.blocks_per_group);
-    printf("inodes_per_group    = %d\n", stats.inodes_per_group);
-    printf("volume_name         = %s\n", stats.volume_name);
-
-    printf("**********************************************\n");
-
-}
-
-static void block_stats(void)
-{
-    uint32_t i;
-
-    printf("**********************************************\n");
-    printf("ext4 blockdev stats\n");
-    printf("bdev->bread_ctr          = %d\n", bd->bread_ctr);
-    printf("bdev->bwrite_ctr         = %d\n", bd->bwrite_ctr);
-
-
-    printf("bcache->ref_blocks       = %d\n", bc->ref_blocks);
-    printf("bcache->max_ref_blocks   = %d\n", bc->max_ref_blocks);
-    printf("bcache->lru_ctr          = %d\n", bc->lru_ctr);
-
-    printf("\n");
-    for (i = 0; i < bc->cnt; ++i) {
-        printf("bcache->refctr[%d]     = %d\n", i, bc->refctr[i]);
-    }
-
-    printf("\n");
-    for (i = 0; i < bc->cnt; ++i) {
-        printf("bcache->lru_id[%d]     = %d\n", i, bc->lru_id[i]);
-    }
-
-    printf("\n");
-    for (i = 0; i < bc->cnt; ++i) {
-        printf("bcache->free_delay[%d] = %d\n", i, bc->free_delay[i]);
-    }
-
-    printf("\n");
-    for (i = 0; i < bc->cnt; ++i) {
-        printf("bcache->lba[%d]        = %d\n", i, bc->lba[i]);
-    }
-
-
-
-    printf("**********************************************\n");
-}
-
-
-int main(int argc, char **argv)
-{
-	int option_index = 0;
-	int	c;
-	int	r;
-	int	i;
-	uint32_t  size;
-	ext4_file f;
-
-    static struct option long_options[] =
-      {
-        {"in",     	required_argument, 0, 'a'},
-        {"rws",     required_argument, 0, 'b'},
-        {"rwc",		required_argument, 0, 'c'},
-        {"cache",   required_argument, 0, 'd'},
-        {0, 0, 0, 0}
-      };
-
-    while(-1 != (c = getopt_long (argc, argv, "a:b:c:d:", long_options, &option_index))) {
-
-    	switch(c){
-    		case 'a':
-    			strcpy(input_name, optarg);
-    			break;
-    		case 'b':
-    			rw_szie = atoi(optarg);
-    			break;
-    		case 'c':
-    			rw_count = atoi(optarg);
-    			break;
-    		case 'd':
-    			cache_mode = atoi(optarg);
-    			break;
-    		default:
-    			printf(usage);
-    			return EXIT_FAILURE;
-
-    	}
-    }
-
-    printf("Test conditions:\n");
-    printf("Imput name: %s\n", input_name);
-    printf("RW size: %d\n",  rw_szie);
-    printf("RW count: %d\n", rw_count);
-    printf("Cache mode: %s\n", cache_mode ? "dynamic" : "static");
-
-
-
-    ext4_filedev_filename(input_name);
-
-    wr_buff = malloc(rw_szie);
-    rd_buff = malloc(rw_szie);
-
-    if(!wr_buff || !rd_buff){
-    	printf("Read-Write allocation ERROR\n");
-    	return EXIT_FAILURE;
-    }
-
-	bd = ext4_filedev_get();
-	bc = ext4_filecache_get();
-
-    if(!bd || !bc){
-    	printf("Block device ERROR\n");
-    	return EXIT_FAILURE;
-    }
-
-	ext4_dmask_set(EXT4_DEBUG_ALL);
-
-	r = ext4_device_register(bd, cache_mode ? 0 : bc, "ext4_filesim");
-	if(r != EOK){
-		printf("ext4_device_register ERROR = %d\n", r);
-		return EXIT_FAILURE;
-	}
-
-	r = ext4_mount("ext4_filesim", "/mp/");
-	if(r != EOK){
-		printf("ext4_mount ERROR = %d\n", r);
-		return EXIT_FAILURE;
-	}
-
-
-	ext4_fremove("/mp/hello.txt");
-	ext4_fremove("/mp/test1");
-	mp_stats();
-	dir_ls("/mp/");
-
-    /*Add hello world file.*/
-    r = ext4_fopen(&f, "/mp/hello.txt", "wb");
-    r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0);
-    r = ext4_fclose(&f);
-
-
-	printf("ext4_fopen: test1\n");
-
-	r = ext4_fopen(&f, "/mp/test1", "wb");
-	if(r != EOK){
-		printf("ext4_fopen ERROR = %d\n", r);
-		return EXIT_FAILURE;
-	}
-
-	printf("ext4_write: %d * %d ..." , rw_count, rw_szie);
-
-	for (i = 0; i < rw_count; ++i) {
-
-		memset(wr_buff, i & 0xFF, rw_szie);
-
-		r = ext4_fwrite(&f, wr_buff, rw_szie, &size);
-
-		if((r != EOK) || (size != rw_szie))
-			break;
-	}
-
-	if(i != rw_count){
-		printf("ERROR: rw_count = %d\n", i);
-		return EXIT_FAILURE;
-	}
-
-	printf("OK\n");
-	r = ext4_fclose(&f);
-	printf("ext4_fopen: test1\n");
-
-	r = ext4_fopen(&f, "/mp/test1", "r+");
-	if(r != EOK){
-		printf("ext4_fopen ERROR = %d\n", r);
-		return EXIT_FAILURE;
-	}
-
-	printf("ext4_read: %d * %d ..." , rw_count, rw_szie);
-
-	for (i = 0; i < rw_count; ++i) {
-		memset(wr_buff, i & 0xFF, rw_szie);
-		r = ext4_fread(&f, rd_buff, rw_szie, &size);
-
-		if((r != EOK) || (size != rw_szie))
-			break;
-
-		if(memcmp(rd_buff, wr_buff, rw_szie)){
-			break;
-		}
-	}
-	if(i != rw_count){
-		printf("ERROR: rw_count = %d\n", i);
-		return EXIT_FAILURE;
-	}
-
-	printf("OK\n");
-
-	r = ext4_fclose(&f);
-
-
-	mp_stats();
-	dir_ls("/mp/");
-
-	block_stats();
-	r = ext4_umount("/mp/");
-
-	printf("Test finish: OK\n");
-    return EXIT_SUCCESS;
-
-}
--- a/src/ext4.h
+++ /dev/null
@@ -1,267 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4.h
- * @brief Ext4 high level operations (files, directories, mountpoints...).
- * 		  Client has to include only this file.
- */
-
-#ifndef EXT4_H_
-#define EXT4_H_
-
-#include <ext4_config.h>
-#include <ext4_blockdev.h>
-#include <stdint.h>
-
-/********************************FILE OPEN FLAGS********************************/
-
-#ifndef O_RDONLY
-#define O_RDONLY	00
-#endif
-
-#ifndef O_WRONLY
-#define O_WRONLY	01
-#endif
-
-#ifndef O_RDWR
-#define O_RDWR		02
-#endif
-
-#ifndef O_CREAT
-#define O_CREAT	    0100
-#endif
-
-#ifndef O_EXCL
-#define O_EXCL		0200
-#endif
-
-#ifndef O_TRUNC
-#define O_TRUNC		01000
-#endif
-
-#ifndef O_APPEND
-#define O_APPEND	02000
-#endif
-
-/********************************FILE SEEK FLAGS*****************************/
-
-#ifndef SEEK_SET
-#define SEEK_SET	0
-#endif
-
-#ifndef SEEK_CUR
-#define SEEK_CUR	1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END	2
-#endif
-
-/********************************OS LOCK INFERFACE***************************/
-
-/**@brief	OS dependent lock interface.*/
-struct ext4_lock {
-
-    /**@brief	Lock access to mountpoint*/
-    void (*lock)(void);
-
-    /**@brief	Unlock access to mountpoint*/
-    void (*unlock)(void);
-};
-
-
-/********************************FILE DESCRIPTOR*****************************/
-
-/**@brief	File descriptor*/
-typedef struct ext4_file {
-
-    /**@brief	Pountpoint handle.*/
-    struct ext4_mountpoint *mp;
-
-    /**@brief	File inode id*/
-    uint32_t inode;
-
-    /**@brief	Open flags.*/
-    uint32_t flags;
-
-    /**@brief	File size.*/
-    uint64_t fsize;
-
-    /**@brief	File position*/
-    uint64_t fpos;
-}ext4_file;
-
-/*****************************DIRECTORY DESCRIPTOR***************************/
-/**@brief	Directory entry types. Copy from ext4_types.h*/
-enum  {
-    EXT4_DIRENTRY_UNKNOWN = 0,
-    EXT4_DIRENTRY_REG_FILE,
-    EXT4_DIRENTRY_DIR,
-    EXT4_DIRENTRY_CHRDEV,
-    EXT4_DIRENTRY_BLKDEV,
-    EXT4_DIRENTRY_FIFO,
-    EXT4_DIRENTRY_SOCK,
-    EXT4_DIRENTRY_SYMLINK
-};
-
-/**@brief	Directory entry descriptor. Copy from ext4_types.h*/
-typedef struct {
-    uint32_t inode;
-    uint16_t entry_length;
-    uint8_t  name_length;
-    union {
-        uint8_t name_length_high;
-        uint8_t inode_type;
-    };
-    uint8_t name[255];
-}ext4_direntry;
-
-typedef struct  {
-    /**@brief 	File descriptor*/
-    ext4_file		f;
-    /**@brief	Current direntry.*/
-    ext4_direntry	de;
-}ext4_dir;
-
-/********************************MOUNT OPERATIONS****************************/
-
-/**@brief	Register a block device to a name.
- *          @warning Block device has to be filled by
- *          @ref EXT4_BLOCKDEV_STATIC_INSTANCE. Block cache may be created
- *          @ref EXT4_BCACHE_STATIC_INSTANCE.
- *          Block cache may by created automaticly when bc parameter is 0.
- * @param   bd block device
- * @param   bd block device cache (0 = automatic cache mode)
- * @param   dev_name register name
- * @param   standard error code*/
-int	ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
-        const char *dev_name);
-
-/**@brief	Mount a block device with EXT4 partition to the mountpoint.
- * @param	dev_name block device name (@ref ext4_device_register)
- * @param	mount_point pount point, for example
- *          -   /
- *          -   /my_partition/
- *          -   /my_second_partition/
- *
- * @return standard error code */
-int	ext4_mount(const char * dev_name,  char *mount_point);
-
-/**@brief	Umount operation.
- * @param	mount_point mount name
- * @return  standard error code */
-int	ext4_umount(char *mount_point);
-
-
-/**@brief   Some of the filesystem params.*/
-struct ext4_mount_stats {
-    uint32_t inodes_count;
-    uint32_t free_inodes_count;
-    uint64_t blocks_count;
-    uint64_t free_blocks_count;
-
-    uint32_t block_size;
-    uint32_t block_group_count;
-    uint32_t blocks_per_group;
-    uint32_t inodes_per_group;
-
-    char volume_name[16];
-};
-
-int ext4_mount_point_stats(const char *mount_point,
-    struct ext4_mount_stats *stats);
-
-/********************************FILE OPERATIONS*****************************/
-
-/**@brief	*/
-int ext4_fremove(const char *path);
-
-/**@brief	File open function.
- * @param	filename, (has to start from mountpoint)
- * 			/my_partition/my_file
- * @param	flags open file flags
- *  |---------------------------------------------------------------|
- *  |   r or rb                 O_RDONLY                            |
- *  |---------------------------------------------------------------|
- *  |   w or wb                 O_WRONLY|O_CREAT|O_TRUNC            |
- *  |---------------------------------------------------------------|
- *  |   a or ab                 O_WRONLY|O_CREAT|O_APPEND           |
- *  |---------------------------------------------------------------|
- *  |   r+ or rb+ or r+b        O_RDWR                              |
- *  |---------------------------------------------------------------|
- *  |   w+ or wb+ or w+b        O_RDWR|O_CREAT|O_TRUNC              |
- *  |---------------------------------------------------------------|
- *  |   a+ or ab+ or a+b        O_RDWR|O_CREAT|O_APPEND             |
- *  |---------------------------------------------------------------|
- *
- * @return	standard error code*/
-int ext4_fopen (ext4_file *f, const char *path, const char *flags);
-
-/**@brief	*/
-int ext4_fclose(ext4_file *f);
-
-/**@brief	*/
-int ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt);
-
-/**@brief	*/
-int ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt);
-
-/**@brief	*/
-int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin);
-
-/**@brief	*/
-uint64_t ext4_ftell (ext4_file *f);
-
-/**@brief	*/
-uint64_t ext4_fsize (ext4_file *f);
-
-/*********************************DIRECTORY OPERATION***********************/
-/**@brief	*/
-int ext4_mkdir(const char *path);
-
-/**@brief	*/
-int ext4_rmdir(const char *path);
-
-/**@brief	*/
-int ext4_dir_open (ext4_dir *d, const char *path);
-
-/**@brief	*/
-int ext4_dir_close(ext4_dir *d);
-
-/**@brief	*/
-ext4_direntry* ext4_entry_get(ext4_dir *d, uint32_t id);
-
-#endif /* EXT4_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4.c
+++ /dev/null
@@ -1,1205 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4.h
- * @brief Ext4 high level operations (file, directory, mountpoints...)
- */
-
-#include <ext4_config.h>
-#include <ext4_blockdev.h>
-#include <ext4_types.h>
-#include <ext4_debug.h>
-#include <ext4_errno.h>
-#include <ext4_fs.h>
-#include <ext4_dir.h>
-#include <ext4_inode.h>
-#include <ext4_super.h>
-#include <ext4_dir_idx.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <ext4.h>
-
-/**@brief	Mount point OS dependent lock*/
-#define EXT4_MP_LOCK(_m)    \
-        do { (_m)->os_locks ? (_m)->os_locks->lock()   : 0; }while(0)
-
-/**@brief	Mount point OS dependent unlock*/
-#define EXT4_MP_UNLOCK(_m)  \
-        do { (_m)->os_locks ? (_m)->os_locks->unlock() : 0;	}while(0)
-
-/**@brief	Mount point descrpitor.*/
-struct ext4_mountpoint {
-
-    /**@brief	Mount point name (@ref ext4_mount)*/
-    const char 		 *name;
-
-    /**@brief	Os dependent lock/unlock functions.*/
-    struct ext4_lock *os_locks;
-
-    /**@brief	Ext4 filesystem internals.*/
-    struct ext4_fs	 fs;
-
-    /**@brief	Dynamic alocation cache flag.*/
-    bool            cache_dynamic;
-};
-
-/**@brief	Block devices descriptor.*/
-struct	_ext4_devices {
-
-    /**@brief	Block device name (@ref ext4_device_register)*/
-    const char				*name;
-
-    /**@brief	Block device handle.*/
-    struct ext4_blockdev	*bd;
-
-    /**@brief	Block cache handle.*/
-    struct ext4_bcache		*bc;
-};
-
-/**@brief	Block devices.*/
-struct	_ext4_devices _bdevices[CONFIG_EXT4_BLOCKDEVS_COUNT];
-
-
-/**@brief	Mountpoints.*/
-struct ext4_mountpoint	_mp[CONFIG_EXT4_MOUNTPOINTS_COUNT];
-
-
-
-int	ext4_device_register(struct ext4_blockdev *bd, struct ext4_bcache *bc,
-        const char *dev_name)
-{
-    uint32_t i;
-    ext4_assert(bd && dev_name);
-
-    for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
-        if(!_bdevices[i].name){
-            _bdevices[i].name   = dev_name;
-            _bdevices[i].bd 	= bd;
-            _bdevices[i].bc 	= bc;
-            return EOK;
-        }
-    }
-    return ENOSPC;
-}
-
-/****************************************************************************/
-
-
-static bool ext4_is_dots(const uint8_t *name, size_t name_size)
-{
-    if ((name_size == 1) && (name[0] == '.'))
-        return true;
-
-    if ((name_size == 2) && (name[0] == '.') && (name[1] == '.'))
-        return true;
-
-    return false;
-}
-
-static int ext4_has_children(bool *has_children, struct ext4_inode_ref *enode)
-{
-
-    struct ext4_fs *fs = enode->fs;
-
-    /* Check if node is directory */
-    if (!ext4_inode_is_type(&fs->sb, enode->inode,
-            EXT4_INODE_MODE_DIRECTORY)) {
-        *has_children = false;
-        return EOK;
-    }
-
-    struct ext4_directory_iterator it;
-    int rc = ext4_dir_iterator_init(&it, enode, 0);
-    if (rc != EOK)
-        return rc;
-
-    /* Find a non-empty directory entry */
-    bool found = false;
-    while (it.current != NULL) {
-        if (it.current->inode != 0) {
-            uint16_t name_size =
-                    ext4_dir_entry_ll_get_name_length(&fs->sb,
-                            it.current);
-            if (!ext4_is_dots(it.current->name, name_size)) {
-                found = true;
-                break;
-            }
-        }
-
-        rc = ext4_dir_iterator_next(&it);
-        if (rc != EOK) {
-            ext4_dir_iterator_fini(&it);
-            return rc;
-        }
-    }
-
-    rc = ext4_dir_iterator_fini(&it);
-    if (rc != EOK)
-        return rc;
-
-    *has_children = found;
-
-    return EOK;
-}
-
-
-static int ext4_link(struct ext4_mountpoint *mp, struct ext4_inode_ref *parent,
-        struct ext4_inode_ref *child, const char *name, uint32_t name_len)
-{
-    /* Check maximum name length */
-    if(name_len > EXT4_DIRECTORY_FILENAME_LEN)
-        return EINVAL;
-
-    /* Add entry to parent directory */
-    int rc = ext4_dir_add_entry(parent, name, name_len,
-            child);
-    if (rc != EOK)
-        return rc;
-
-    /* Fill new dir -> add '.' and '..' entries */
-    if (ext4_inode_is_type(&mp->fs.sb, child->inode,
-            EXT4_INODE_MODE_DIRECTORY)) {
-        rc = ext4_dir_add_entry(child, ".", strlen("."),
-                child);
-        if (rc != EOK) {
-            ext4_dir_remove_entry(parent, name, strlen(name));
-            return rc;
-        }
-
-        rc = ext4_dir_add_entry(child, "..", strlen(".."),
-                parent);
-        if (rc != EOK) {
-            ext4_dir_remove_entry(parent, name, strlen(name));
-            ext4_dir_remove_entry(child, ".", strlen("."));
-            return rc;
-        }
-
-#if CONFIG_DIR_INDEX_ENABLE
-        /* Initialize directory index if supported */
-        if (ext4_sb_check_feature_compatible(&mp->fs.sb,
-                EXT4_FEATURE_COMPAT_DIR_INDEX)) {
-            rc = ext4_dir_dx_init(child);
-            if (rc != EOK)
-                return rc;
-
-            ext4_inode_set_flag(child->inode,
-                    EXT4_INODE_FLAG_INDEX);
-            child->dirty = true;
-        }
-#endif
-
-        uint16_t parent_links =
-                ext4_inode_get_links_count(parent->inode);
-        parent_links++;
-        ext4_inode_set_links_count(parent->inode, parent_links);
-
-        parent->dirty = true;
-    }
-
-    uint16_t child_links =
-            ext4_inode_get_links_count(child->inode);
-    child_links++;
-    ext4_inode_set_links_count(child->inode, child_links);
-
-    child->dirty = true;
-
-    return EOK;
-}
-
-static int ext4_unlink(struct ext4_mountpoint *mp,
-    struct ext4_inode_ref *parent, struct ext4_inode_ref *child_inode_ref,
-    const char *name, uint32_t name_len)
-{
-    bool has_children;
-    int rc = ext4_has_children(&has_children, child_inode_ref);
-    if (rc != EOK)
-        return rc;
-
-    /* Cannot unlink non-empty node */
-    if (has_children)
-        return ENOTSUP;
-
-    /* Remove entry from parent directory */
-
-    rc = ext4_dir_remove_entry(parent, name, name_len);
-    if (rc != EOK)
-        return rc;
-
-
-    uint32_t lnk_count =
-            ext4_inode_get_links_count(child_inode_ref->inode);
-    lnk_count--;
-
-    bool is_dir = ext4_inode_is_type(&mp->fs.sb, child_inode_ref->inode,
-            EXT4_INODE_MODE_DIRECTORY);
-
-    /* If directory - handle links from parent */
-    if ((lnk_count <= 1) && (is_dir)) {
-        ext4_assert(lnk_count == 1);
-
-        lnk_count--;
-
-        uint32_t parent_lnk_count = ext4_inode_get_links_count(
-                parent->inode);
-
-        parent_lnk_count--;
-        ext4_inode_set_links_count(parent->inode, parent_lnk_count);
-
-        parent->dirty = true;
-    }
-
-    /*
-     * TODO: Update timestamps of the parent
-     * (when we have wall-clock time).
-     *
-     * ext4_inode_set_change_inode_time(parent->inode, (uint32_t) now);
-     * ext4_inode_set_modification_time(parent->inode, (uint32_t) now);
-     * parent->dirty = true;
-     */
-
-    /*
-     * TODO: Update timestamp for inode.
-     *
-     * ext4_inode_set_change_inode_time(child_inode_ref->inode,
-     *     (uint32_t) now);
-     */
-
-    ext4_inode_set_deletion_time(child_inode_ref->inode, 1);
-    ext4_inode_set_links_count(child_inode_ref->inode, lnk_count);
-    child_inode_ref->dirty = true;
-
-    return EOK;
-}
-
-/****************************************************************************/
-
-int			ext4_mount(const char * dev_name,  char *mount_point)
-{
-    ext4_assert(mount_point && dev_name);
-    int r = EOK;
-    int i;
-
-    uint32_t bsize;
-    struct ext4_blockdev	*bd = 0;
-    struct ext4_bcache		*bc = 0;
-    struct ext4_mountpoint	*mp = 0;
-
-    if(mount_point[strlen(mount_point) - 1] != '/')
-        return ENOTSUP;
-
-    for (i = 0; i < CONFIG_EXT4_BLOCKDEVS_COUNT; ++i) {
-        if(_bdevices[i].name){
-            if(!strcmp(dev_name, _bdevices[i].name)){
-                bd = _bdevices[i].bd;
-                bc = _bdevices[i].bc;
-                break;
-            }
-        }
-    }
-
-    if(!bd)
-        return ENODEV;
-
-    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
-        if(!_mp[i].name){
-            _mp[i].name = mount_point;
-            mp = &_mp[i];
-            break;
-        }
-    }
-
-    if(!mp)
-        return ENOMEM;
-
-    r = ext4_block_init(bd);
-    if(r != EOK)
-        return r;
-
-    r = ext4_fs_init(&mp->fs, bd);
-    if(r != EOK){
-        ext4_block_fini(bd);
-        return r;
-    }
-
-    bsize = ext4_sb_get_block_size(&mp->fs.sb);
-    ext4_block_set_lb_size(bd, bsize);
-
-
-    mp->cache_dynamic = 0;
-
-    if(!bc){
-        /*Automatic block cache alloc.*/
-        mp->cache_dynamic = 1;
-        bc = malloc(sizeof(struct ext4_bcache));
-
-        r = ext4_bcache_init_dynamic(bc, 8, bsize);
-        if(r != EOK){
-            free(bc);
-            ext4_block_fini(bd);
-            return r;
-        }
-    }
-
-    if(bsize != bc->itemsize)
-        return ENOTSUP;
-
-
-    /*Bind block cache to block device*/
-    r = ext4_block_bind_bcache(bd, bc);
-    if(r != EOK){
-        ext4_block_fini(bd);
-        if(mp->cache_dynamic){
-            ext4_bcache_fini_dynamic(bc);
-            free(bc);
-        }
-        return r;
-    }
-
-    return r;
-}
-
-
-int			ext4_umount(char *mount_point)
-{
-    int 	i;
-    int 	r = EOK;
-    struct ext4_mountpoint	*mp = 0;
-
-    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
-        if(_mp[i].name){
-            if(!strcmp(_mp[i].name, mount_point))
-                mp = &_mp[i];
-            break;
-        }
-    }
-
-    if(!mp)
-        return ENODEV;
-
-    r = ext4_fs_fini(&mp->fs);
-    if(r != EOK)
-        return r;
-
-    mp->name = 0;
-
-    if(mp->cache_dynamic){
-        ext4_bcache_fini_dynamic(mp->fs.bdev->bc);
-        free(mp->fs.bdev->bc);
-    }
-
-    return ext4_block_fini(mp->fs.bdev);
-}
-
-int ext4_mount_point_stats(const char *mount_point,
-    struct ext4_mount_stats *stats)
-{
-    uint32_t i;
-    struct ext4_mountpoint    *mp = 0;
-
-    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
-        if(_mp[i].name){
-            if(!strcmp(_mp[i].name, mount_point))
-                mp = &_mp[i];
-            break;
-        }
-    }
-
-    if(!mp)
-        return ENOENT;
-
-
-    EXT4_MP_LOCK(mp);
-    stats->inodes_count      = ext4_get32(&mp->fs.sb, inodes_count);
-    stats->free_inodes_count = ext4_get32(&mp->fs.sb, free_inodes_count);
-    stats->blocks_count      = ext4_sb_get_blocks_cnt(&mp->fs.sb);
-    stats->free_blocks_count = ext4_sb_get_free_blocks_cnt(&mp->fs.sb);
-    stats->block_size        = ext4_sb_get_block_size(&mp->fs.sb);
-
-    stats->block_group_count = ext4_block_group_cnt(&mp->fs.sb);
-    stats->blocks_per_group  = ext4_get32(&mp->fs.sb, blocks_per_group);
-    stats->inodes_per_group  = ext4_get32(&mp->fs.sb, inodes_per_group);
-
-    memcpy(stats->volume_name, mp->fs.sb.volume_name, 16);
-    EXT4_MP_UNLOCK(mp);
-
-    return EOK;
-}
-
-/********************************FILE OPERATIONS*****************************/
-
-static struct ext4_mountpoint*  ext4_get_mount(const char *path)
-{
-    int i;
-    for (i = 0; i < CONFIG_EXT4_MOUNTPOINTS_COUNT; ++i) {
-        if(_mp[i].name){
-            if(!strncmp(_mp[i].name, path, strlen(_mp[i].name)))
-                return &_mp[i];
-        }
-    }
-    return 0;
-}
-
-
-static int ext4_path_check(const char *path, bool* is_goal)
-{
-    int i;
-
-    for (i = 0; i < EXT4_DIRECTORY_FILENAME_LEN; ++i) {
-
-        if(path[i] == '/'){
-            *is_goal = false;
-            return i;
-        }
-
-        if(path[i] == 0){
-            *is_goal = true;
-            return i;
-        }
-    }
-
-    return 0;
-}
-
-
-static bool ext4_parse_flags(const char *flags, uint32_t *file_flags)
-{
-    if(!flags)
-        return false;
-
-    if(!strcmp(flags, "r") || !strcmp(flags, "rb")){
-        *file_flags = O_RDONLY;
-        return true;
-    }
-
-    if(!strcmp(flags, "w") || !strcmp(flags, "wb")){
-        *file_flags = O_WRONLY | O_CREAT | O_TRUNC;
-        return true;
-    }
-
-    if(!strcmp(flags, "a") || !strcmp(flags, "ab")){
-        *file_flags = O_WRONLY | O_CREAT | O_APPEND	;
-        return true;
-    }
-
-    if(!strcmp(flags, "r+") || !strcmp(flags, "rb+") || !strcmp(flags, "r+b")){
-        *file_flags = O_RDWR;
-        return true;
-    }
-
-    if(!strcmp(flags, "w+") || !strcmp(flags, "wb+") || !strcmp(flags, "w+b")){
-        *file_flags = O_RDWR | O_CREAT | O_TRUNC;
-        return true;
-    }
-
-    if(!strcmp(flags, "a+") || !strcmp(flags, "ab+") || !strcmp(flags, "a+b")){
-        *file_flags = O_RDWR | O_CREAT | O_APPEND;
-        return true;
-    }
-
-    return false;
-}
-
-/****************************************************************************/
-
-static int ext4_generic_open (ext4_file *f, const char *path,
-        const char *flags, bool file_expect)
-{
-    struct ext4_mountpoint *mp = ext4_get_mount(path);
-    struct ext4_directory_search_result result;
-    struct ext4_inode_ref	ref;
-    bool	is_goal = false;
-    uint8_t	inode_type;
-    int		r = ENOENT;
-    uint32_t next_inode;
-
-    f->mp = 0;
-
-    if(!mp)
-        return ENOENT;
-
-    if(ext4_parse_flags(flags, &f->flags) == false)
-        return EINVAL;
-
-    /*Skip mount point*/
-    path += strlen(mp->name);
-
-    EXT4_MP_LOCK(mp);
-
-    /*Load root*/
-    r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &ref);
-
-    if(r != EOK)
-        return r;
-
-    int len = ext4_path_check(path, &is_goal);
-
-    /*If root open was request.*/
-    if(!len && is_goal)
-        goto IsGoal;
-
-    while(1){
-
-        len = ext4_path_check(path, &is_goal);
-
-        if(!len){
-            r = ENOENT;
-            break;
-        }
-
-        r = ext4_dir_find_entry(&result, &ref, path, len);
-        if(r != EOK){
-
-            if(r != ENOENT)
-                break;
-
-            if(!(f->flags & O_CREAT))
-                break;
-
-            /*O_CREAT allows to create new entry*/
-            struct ext4_inode_ref	child_ref;
-            r = ext4_fs_alloc_inode(&mp->fs, &child_ref, !is_goal);
-            if(r != EOK)
-                break;
-
-            /*Destroy last result*/
-            ext4_dir_destroy_result(&ref, &result);
-
-            /*Link with root dir.*/
-            r = ext4_link(mp, &ref, &child_ref, path, len);
-            if(r != EOK){
-                /*Fali. Free new inode.*/
-                ext4_fs_free_inode(&child_ref);
-                /*We do not want to write new inode.
-                  But block has to be released.*/
-                child_ref.dirty = false;
-                ext4_fs_put_inode_ref(&child_ref);
-                break;
-            }
-
-            ext4_fs_put_inode_ref(&child_ref);
-
-            continue;
-        }
-
-        next_inode = result.dentry->inode;
-        inode_type = ext4_dir_entry_ll_get_inode_type(&mp->fs.sb, result.dentry);
-
-        r = ext4_dir_destroy_result(&ref, &result);
-        if(r != EOK)
-            break;
-
-        /*If expected file error*/
-        if((inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE)
-                && !file_expect && is_goal){
-            r = ENOENT;
-            break;
-        }
-
-        /*If expected directory error*/
-        if((inode_type == EXT4_DIRECTORY_FILETYPE_DIR)
-                && file_expect && is_goal){
-            r = ENOENT;
-            break;
-        }
-
-        r = ext4_fs_put_inode_ref(&ref);
-        if(r != EOK)
-            break;
-
-        r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &ref);
-        if(r != EOK)
-            break;
-
-        if(is_goal)
-            break;
-
-        path += len + 1;
-    };
-
-    if(r != EOK){
-        ext4_fs_put_inode_ref(&ref);
-        EXT4_MP_UNLOCK(mp);
-        return r;
-    }
-
-    IsGoal:
-    if(is_goal){
-
-        if(f->flags & O_TRUNC){
-            /*Turncate.*/
-            ext4_block_delay_cache_flush(mp->fs.bdev, 1);
-            /*Truncate may be IO heavy.
-             Do it with delayed cache flush mode.*/
-            r = ext4_fs_truncate_inode(&ref, 0);
-            ext4_block_delay_cache_flush(mp->fs.bdev, 0);
-
-            if(r != EOK){
-                ext4_fs_put_inode_ref(&ref);
-                EXT4_MP_UNLOCK(mp);
-                return r;
-            }
-        }
-
-        f->mp = mp;
-        f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
-        f->inode = ref.index;
-        f->fpos  = 0;
-
-        if(f->flags & O_APPEND)
-            f->fpos = f->fsize;
-
-    }
-
-    r = ext4_fs_put_inode_ref(&ref);
-    EXT4_MP_UNLOCK(mp);
-    return r;
-}
-
-/****************************************************************************/
-
-int ext4_fremove(const char *path)
-{
-    struct ext4_mountpoint *mp = ext4_get_mount(path);
-    struct ext4_directory_search_result result;
-    bool	is_goal = false;
-    uint8_t	inode_type;
-    int		r = ENOENT;
-    uint32_t next_inode;
-
-    struct ext4_inode_ref	parent;
-    struct ext4_inode_ref	child;
-    int len = 0;
-
-    if(!mp)
-        return ENOENT;
-
-
-    /*Skip mount point*/
-    path += strlen(mp->name);
-
-    /*Lock mountpoint*/
-    EXT4_MP_LOCK(mp);
-
-    /*Load root*/
-    r = ext4_fs_get_inode_ref(&mp->fs, EXT4_INODE_ROOT_INDEX, &parent);
-
-    if(r != EOK){
-        EXT4_MP_UNLOCK(mp);
-        return r;
-    }
-
-    while(1){
-
-        len = ext4_path_check(path, &is_goal);
-
-        if(!len){
-            r = ENOENT;
-            break;
-        }
-
-        r = ext4_dir_find_entry(&result, &parent, path, len);
-        if(r != EOK){
-            ext4_dir_destroy_result(&parent, &result);
-            break;
-        }
-
-        next_inode = result.dentry->inode;
-        inode_type = ext4_dir_entry_ll_get_inode_type(&mp->fs.sb,
-                result.dentry);
-
-        r = ext4_dir_destroy_result(&parent, &result);
-        if(r != EOK)
-            break;
-
-        /*If expected file error*/
-        if((inode_type == EXT4_DIRECTORY_FILETYPE_REG_FILE) && !is_goal){
-            r = ENOENT;
-            break;
-        }
-
-        /*If expected directory error*/
-        if((inode_type == EXT4_DIRECTORY_FILETYPE_DIR) && is_goal){
-            r = ENOENT;
-            break;
-        }
-
-        if(is_goal)
-            break;
-
-        r = ext4_fs_put_inode_ref(&parent);
-        if(r != EOK)
-            break;
-
-
-        r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &parent);
-        if(r != EOK)
-            break;
-
-        path += len + 1;
-    };
-
-    if(r != EOK){
-        /*No entry or other error.*/
-        ext4_fs_put_inode_ref(&parent);
-        EXT4_MP_UNLOCK(mp);
-        return r;
-    }
-
-
-    /*We have file to delete. Load it.*/
-    r = ext4_fs_get_inode_ref(&mp->fs, next_inode, &child);
-    if(r != EOK){
-        /*Parent free*/
-        ext4_fs_put_inode_ref(&parent);
-        EXT4_MP_UNLOCK(mp);
-        return r;
-    }
-
-    /*Turncate.*/
-    ext4_block_delay_cache_flush(mp->fs.bdev, 1);
-
-    /*Truncate may be IO heavy. Do it with delayed cache flush mode.*/
-    r = ext4_fs_truncate_inode(&child, 0);
-
-    ext4_block_delay_cache_flush(mp->fs.bdev, 0);
-    if(r != EOK)
-        goto Finish;
-
-    /*Unlink from parent.*/
-    r = ext4_unlink(mp, &parent, &child, path, len);
-    if(r != EOK)
-        goto Finish;
-
-    r = ext4_fs_free_inode(&child);
-    if(r != EOK)
-        goto Finish;
-
-
-    Finish:
-    ext4_fs_put_inode_ref(&child);
-    ext4_fs_put_inode_ref(&parent);
-    EXT4_MP_UNLOCK(mp);
-    return r;
-}
-
-
-int	ext4_fopen (ext4_file *f, const char *path, const char *flags)
-{
-    return ext4_generic_open(f, path, flags, true);
-}
-
-int	ext4_fclose(ext4_file *f)
-{
-    ext4_assert(f && f->mp);
-
-    f->mp    = 0;
-    f->flags = 0;
-    f->inode = 0;
-    f->fpos  = f->fsize = 0;
-
-    return EOK;
-}
-int	ext4_fread (ext4_file *f, void *buf, uint32_t size, uint32_t *rcnt)
-{
-    int		 r = EOK;
-    uint32_t u;
-    uint32_t fblock;
-    struct ext4_block b;
-    uint8_t	*u8_buf = buf;
-    struct ext4_inode_ref ref;
-    uint32_t sblock;
-    uint32_t block_size;
-
-    ext4_assert(f && f->mp);
-
-    if(f->flags & O_WRONLY)
-        return EPERM;
-
-    if(!size)
-        return EOK;
-
-    EXT4_MP_LOCK(f->mp);
-
-    if(rcnt)
-        *rcnt = 0;
-
-    r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
-    if(r != EOK){
-        EXT4_MP_UNLOCK(f->mp);
-        return r;
-    }
-
-    /*Sync file size*/
-    f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
-
-
-    block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
-    size = size > (f->fsize - f->fpos) ? (f->fsize - f->fpos) : size;
-
-    sblock 	= (f->fpos) / block_size;
-
-    u = (f->fpos) % block_size;
-
-
-    if(u){
-
-        uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
-
-        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
-        if(r != EOK)
-            goto Finish;
-
-        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
-        if(r != EOK)
-            goto Finish;
-
-        memcpy(u8_buf, b.data + u, ll);
-
-        r = ext4_block_set(f->mp->fs.bdev, &b);
-        if(r != EOK)
-            goto Finish;
-
-        u8_buf  += ll;
-        size    -= ll;
-        f->fpos += ll;
-
-        if(rcnt)
-            *rcnt += ll;
-
-        sblock++;
-    }
-
-    while(size >= block_size){
-
-        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
-        if(r != EOK)
-            goto Finish;
-
-        r = ext4_block_get_direct(f->mp->fs.bdev, u8_buf, fblock);
-        if(r != EOK)
-            goto Finish;
-
-
-        u8_buf  += block_size;
-        size    -= block_size;
-        f->fpos += block_size;
-
-        if(rcnt)
-            *rcnt += block_size;
-
-        sblock++;
-    }
-
-    if(size){
-        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
-        if(r != EOK)
-            goto Finish;
-
-        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
-        if(r != EOK)
-            goto Finish;
-
-        memcpy(u8_buf, b.data , size);
-
-        r = ext4_block_set(f->mp->fs.bdev, &b);
-        if(r != EOK)
-            goto Finish;
-
-        f->fpos += size;
-
-        if(rcnt)
-            *rcnt += size;
-    }
-
-    Finish:
-    ext4_fs_put_inode_ref(&ref);
-    EXT4_MP_UNLOCK(f->mp);
-    return r;
-}
-
-int	ext4_fwrite(ext4_file *f, void *buf, uint32_t size, uint32_t *wcnt)
-{
-    int		 r = EOK;
-    uint32_t u;
-    uint32_t fblock;
-    struct ext4_block b;
-    uint8_t	*u8_buf = buf;
-    struct ext4_inode_ref ref;
-    uint32_t sblock;
-    uint32_t file_blocks;
-    uint32_t block_size;
-
-    ext4_assert(f && f->mp);
-
-    if(f->flags & O_RDONLY)
-        return EPERM;
-
-    if(!size)
-        return EOK;
-
-    EXT4_MP_LOCK(f->mp);
-
-    if(wcnt)
-        *wcnt = 0;
-
-    r = ext4_fs_get_inode_ref(&f->mp->fs, f->inode, &ref);
-    if(r != EOK){
-        EXT4_MP_UNLOCK(f->mp);
-        return r;
-    }
-
-    /*Sync file size*/
-    f->fsize = ext4_inode_get_size(&f->mp->fs.sb, ref.inode);
-
-    block_size = ext4_sb_get_block_size(&f->mp->fs.sb);
-
-    file_blocks = (f->fsize / block_size);
-
-    if(f->fsize % block_size)
-        file_blocks++;
-
-    sblock 	= (f->fpos) / block_size;
-
-    u = (f->fpos) % block_size;
-
-
-    if(u){
-        uint32_t ll = size > (block_size - u) ? (block_size - u) : size;
-
-        r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
-        if(r != EOK)
-            goto Finish;
-
-        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
-        if(r != EOK)
-            goto Finish;
-
-        memcpy(b.data + u, u8_buf, ll);
-        b.dirty = true;
-
-        r = ext4_block_set(f->mp->fs.bdev, &b);
-        if(r != EOK)
-            goto Finish;
-
-        u8_buf  += ll;
-        size    -= ll;
-        f->fpos += ll;
-
-        if(wcnt)
-            *wcnt += ll;
-
-        sblock++;
-    }
-
-
-    /*Start delay cache flush mode.*/
-    r = ext4_block_delay_cache_flush(f->mp->fs.bdev, 1);
-    if(r != EOK)
-        goto Finish;
-
-    while(size >= block_size){
-
-        if(sblock < file_blocks){
-            r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
-            if(r != EOK)
-                break;
-        }
-        else {
-            r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
-            if(r != EOK)
-                break;
-        }
-
-        r = ext4_block_set_direct(f->mp->fs.bdev, u8_buf, fblock);
-        if(r != EOK)
-            break;
-
-        u8_buf  += block_size;
-        size    -= block_size;
-        f->fpos += block_size;
-
-        if(wcnt)
-            *wcnt += block_size;
-
-        sblock++;
-    }
-
-    /*Stop delay cache flush mode*/
-    ext4_block_delay_cache_flush(f->mp->fs.bdev, 0);
-
-    if(r != EOK)
-        goto Finish;
-
-    if(size){
-        if(sblock < file_blocks){
-            r = ext4_fs_get_inode_data_block_index(&ref, sblock, &fblock);
-            if(r != EOK)
-                goto Finish;
-        }
-        else {
-            r = ext4_fs_append_inode_block(&ref, &fblock, &sblock);
-            if(r != EOK)
-                goto Finish;
-        }
-
-        r = ext4_block_get(f->mp->fs.bdev, &b, fblock);
-        if(r != EOK)
-            goto Finish;
-
-        memcpy(b.data, u8_buf , size);
-        b.dirty = true;
-
-        r = ext4_block_set(f->mp->fs.bdev, &b);
-        if(r != EOK)
-            goto Finish;
-
-        f->fpos += size;
-
-        if(wcnt)
-            *wcnt += size;
-    }
-
-    if(f->fpos > f->fsize){
-        f->fsize = f->fpos;
-        ext4_inode_set_size(ref.inode, f->fsize);
-        ref.dirty = true;
-    }
-
-    Finish:
-    ext4_fs_put_inode_ref(&ref);
-    EXT4_MP_UNLOCK(f->mp);
-    return r;
-
-}
-
-
-
-int ext4_fseek (ext4_file *f, uint64_t offset, uint32_t origin)
-{
-    switch(origin){
-    case SEEK_SET:
-
-        if(offset > f->fsize)
-            return EINVAL;
-
-        f->fpos = offset;
-        return EOK;
-    case SEEK_CUR:
-        if((offset + f->fpos) > f->fsize)
-            return EINVAL;
-
-        f->fpos += offset;
-        return EOK;
-    case SEEK_END:
-        if(offset > f->fsize)
-            return EINVAL;
-        f->fpos = f->fsize - offset;
-        return EOK;
-
-    }
-
-    return EINVAL;
-}
-
-uint64_t ext4_ftell (ext4_file *f)
-{
-    return  f->fpos;
-}
-
-uint64_t ext4_fsize (ext4_file *f)
-{
-    return  f->fsize;
-}
-
-/*********************************DIRECTORY OPERATION************************/
-
-int	ext4_dir_open (ext4_dir *d, const char *path)
-{
-    return ext4_generic_open(&d->f, path, "r", false);
-}
-
-int	ext4_dir_close(ext4_dir *d)
-{
-    return ext4_fclose(&d->f);
-}
-
-ext4_direntry*	ext4_entry_get(ext4_dir *d, uint32_t id)
-{
-    int 	 r;
-    uint32_t i;
-    ext4_direntry *de = 0;
-    struct ext4_inode_ref dir;
-    struct ext4_directory_iterator it;
-
-    EXT4_MP_LOCK(d->f.mp);
-
-    r = ext4_fs_get_inode_ref(&d->f.mp->fs, d->f.inode, &dir);
-    if(r != EOK){
-        goto Finish;
-    }
-
-    r = ext4_dir_iterator_init(&it, &dir, 0);
-    if(r != EOK){
-        ext4_fs_put_inode_ref(&dir);
-        goto Finish;
-    }
-
-    i = 0;
-    while(r == EOK){
-
-        if(!it.current)
-            break;
-
-        if(i == id){
-            memcpy(&d->de, it.current, sizeof(ext4_direntry));
-            de = &d->de;
-            break;
-        }
-
-
-        i++;
-        r = ext4_dir_iterator_next(&it);
-    }
-
-    ext4_dir_iterator_fini(&it);
-    ext4_fs_put_inode_ref(&dir);
-
-    Finish:
-    EXT4_MP_UNLOCK(d->f.mp);
-    return de;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_balloc.c
+++ /dev/null
@@ -1,609 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_balloc.c
- * @brief Physical block allocator.
- */
-
-#include <ext4_config.h>
-#include <ext4_balloc.h>
-#include <ext4_super.h>
-#include <ext4_block_group.h>
-#include <ext4_fs.h>
-#include <ext4_bitmap.h>
-#include <ext4_inode.h>
-
-
-
-static uint32_t ext4_balloc_get_bgid_of_block(struct ext4_sblock *s,
-    uint32_t baddr)
-{
-    if(ext4_get32(s, first_data_block))
-        baddr--;
-
-    return baddr / ext4_get32(s, blocks_per_group);
-}
-
-
-uint32_t ext4_balloc_get_first_data_block_in_group(struct ext4_sblock *s,
-    struct ext4_block_group_ref * bg_ref)
-{
-    uint32_t block_group_count 		 = ext4_block_group_cnt(s);
-    uint32_t inode_table_first_block =
-            ext4_bg_get_inode_table_first_block(bg_ref->block_group, s);
-    uint32_t block_size 			 = ext4_sb_get_block_size(s);
-
-    uint16_t inode_size 	  = ext4_get16(s, inode_size);
-    uint32_t inodes_per_group = ext4_get32(s, inodes_per_group);
-
-    uint32_t inode_table_bytes;
-
-
-    if (bg_ref->index < block_group_count - 1) {
-        inode_table_bytes = inodes_per_group * inode_size;
-    } else {
-        /* Last block group could be smaller */
-        uint32_t inodes_count_total =	ext4_get32(s, inodes_count);
-        inode_table_bytes =
-                (inodes_count_total - ((block_group_count - 1) *
-                        inodes_per_group)) * inode_size;
-    }
-
-    uint32_t inode_table_blocks = inode_table_bytes / block_size;
-
-    if (inode_table_bytes % block_size)
-        inode_table_blocks++;
-
-    return inode_table_first_block + inode_table_blocks;
-}
-
-int ext4_balloc_free_block(struct ext4_inode_ref *inode_ref, uint32_t baddr)
-{
-    struct ext4_fs 	     *fs   = inode_ref->fs;
-    struct ext4_sblock   *sb   = &fs->sb;
-
-
-    uint32_t block_group    = ext4_balloc_get_bgid_of_block(sb, baddr);
-    uint32_t index_in_group	= ext4_fs_baddr2_index_in_group(sb, baddr);
-
-    /* Load block group reference */
-    struct ext4_block_group_ref bg_ref;
-    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    /* Load block with bitmap */
-    uint32_t bitmap_block_addr =
-            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
-
-    struct	ext4_block bitmap_block;
-
-    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Modify bitmap */
-    ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
-    bitmap_block.dirty = true;
-
-    /* Release block with bitmap */
-    rc = ext4_block_set(fs->bdev, &bitmap_block);
-    if (rc != EOK) {
-        /* Error in saving bitmap */
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
-
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-
-    /* Update superblock free blocks count */
-    uint64_t sb_free_blocks =
-            ext4_sb_get_free_blocks_cnt(sb);
-    sb_free_blocks++;
-    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
-
-    /* Update inode blocks count */
-    uint64_t ino_blocks =
-            ext4_inode_get_blocks_count(sb, inode_ref->inode);
-    ino_blocks -= block_size / EXT4_INODE_BLOCK_SIZE;
-    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
-    inode_ref->dirty = true;
-
-    /* Update block group free blocks count */
-    uint32_t free_blocks =
-            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
-    free_blocks++;
-    ext4_bg_set_free_blocks_count(bg_ref.block_group,
-        sb, free_blocks);
-
-    bg_ref.dirty = true;
-
-    /* Release block group reference */
-    rc = ext4_fs_put_block_group_ref(&bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    return EOK;
-}
-
-int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first,
-    uint32_t count)
-{
-    struct ext4_fs *fs = inode_ref->fs;
-    struct ext4_sblock *sb = &fs->sb;
-
-    /* Compute indexes */
-    uint32_t block_group_first =
-            ext4_balloc_get_bgid_of_block(sb, first);
-    uint32_t block_group_last =
-            ext4_balloc_get_bgid_of_block(sb, first + count - 1);
-
-    ext4_assert(block_group_first == block_group_last);
-
-    /* Load block group reference */
-    struct ext4_block_group_ref bg_ref;
-    int rc = ext4_fs_get_block_group_ref(fs, block_group_first, &bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    uint32_t index_in_group_first =
-            ext4_fs_baddr2_index_in_group(sb, first);
-
-    /* Load block with bitmap */
-    uint32_t bitmap_block_addr =
-            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
-
-    struct	ext4_block bitmap_block;
-
-    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Modify bitmap */
-    ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, count);
-    bitmap_block.dirty = true;
-
-    /* Release block with bitmap */
-    rc = ext4_block_set(fs->bdev, &bitmap_block);
-    if (rc != EOK) {
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
-
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-
-    /* Update superblock free blocks count */
-    uint64_t sb_free_blocks =
-            ext4_sb_get_free_blocks_cnt(sb);
-    sb_free_blocks += count;
-    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
-
-    /* Update inode blocks count */
-    uint64_t ino_blocks =
-            ext4_inode_get_blocks_count(sb, inode_ref->inode);
-    ino_blocks -= count * (block_size / EXT4_INODE_BLOCK_SIZE);
-    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
-    inode_ref->dirty = true;
-
-    /* Update block group free blocks count */
-    uint32_t free_blocks =
-            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
-    free_blocks += count;
-    ext4_bg_set_free_blocks_count(bg_ref.block_group,
-        sb, free_blocks);
-    bg_ref.dirty = true;
-
-    /* Release block group reference */
-    rc = ext4_fs_put_block_group_ref(&bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    return EOK;
-}
-
-static uint32_t ext4_balloc_find_goal(struct ext4_inode_ref *inode_ref)
-{
-    uint32_t goal = 0;
-
-    struct ext4_sblock *sb = &inode_ref->fs->sb;
-
-    uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-    uint32_t inode_block_count = inode_size / block_size;
-
-    if (inode_size % block_size != 0)
-        inode_block_count++;
-
-    /* If inode has some blocks, get last block address + 1 */
-    if (inode_block_count > 0) {
-        int rc = ext4_fs_get_inode_data_block_index(inode_ref,
-                inode_block_count - 1, &goal);
-        if (rc != EOK)
-            return 0;
-
-        if (goal != 0) {
-            goal++;
-            return goal;
-        }
-
-        /* If goal == 0, sparse file -> continue */
-    }
-
-    /* Identify block group of inode */
-
-    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
-    uint32_t block_group = (inode_ref->index - 1) / inodes_per_group;
-    block_size = ext4_sb_get_block_size(sb);
-
-    /* Load block group reference */
-    struct ext4_block_group_ref bg_ref;
-    int rc = ext4_fs_get_block_group_ref(inode_ref->fs,
-            block_group, &bg_ref);
-    if (rc != EOK)
-        return 0;
-
-    /* Compute indexes */
-    uint32_t block_group_count = ext4_block_group_cnt(sb);
-    uint32_t inode_table_first_block =
-            ext4_bg_get_inode_table_first_block(bg_ref.block_group, sb);
-    uint16_t inode_table_item_size = ext4_get16(sb, inode_size);
-    uint32_t inode_table_bytes;
-
-    /* Check for last block group */
-    if (block_group < block_group_count - 1) {
-        inode_table_bytes = inodes_per_group * inode_table_item_size;
-    } else {
-        /* Last block group could be smaller */
-        uint32_t inodes_count_total = ext4_get32(sb, inodes_count);
-
-        inode_table_bytes =
-                (inodes_count_total - ((block_group_count - 1) *
-                        inodes_per_group)) * inode_table_item_size;
-    }
-
-    uint32_t inode_table_blocks = inode_table_bytes / block_size;
-
-    if (inode_table_bytes % block_size)
-        inode_table_blocks++;
-
-    goal = inode_table_first_block + inode_table_blocks;
-
-    ext4_fs_put_block_group_ref(&bg_ref);
-
-    return goal;
-}
-
-
-int ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref,
-    uint32_t *fblock)
-{
-    uint32_t allocated_block = 0;
-    uint32_t bitmap_block_addr;
-    uint32_t rel_block_idx = 0;
-
-    struct	ext4_block bitmap_block;
-
-    /* Find GOAL */
-    uint32_t goal = ext4_balloc_find_goal(inode_ref);
-    if (goal == 0) {
-        /* no goal found => partition is full */
-        return ENOSPC;
-    }
-
-    struct ext4_sblock *sb = &inode_ref->fs->sb;
-
-    /* Load block group number for goal and relative index */
-    uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, goal);
-    uint32_t index_in_group =
-            ext4_fs_baddr2_index_in_group(sb, goal);
-
-    /* Load block group reference */
-    struct ext4_block_group_ref bg_ref;
-    int rc = ext4_fs_get_block_group_ref(inode_ref->fs,
-            block_group, &bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    /* Compute indexes */
-    uint32_t first_in_group =
-            ext4_balloc_get_first_data_block_in_group(sb, &bg_ref);
-
-    uint32_t first_in_group_index =
-            ext4_fs_baddr2_index_in_group(sb, first_in_group);
-
-    if (index_in_group < first_in_group_index)
-        index_in_group = first_in_group_index;
-
-    /* Load block with bitmap */
-    bitmap_block_addr =
-            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
-
-    rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block,
-            bitmap_block_addr);
-    if (rc != EOK) {
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
-
-    /* Check if goal is free */
-    if (ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group)) {
-        ext4_bmap_bit_set(bitmap_block.data, index_in_group);
-        bitmap_block.dirty = true;
-        rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
-        if (rc != EOK) {
-            ext4_fs_put_block_group_ref(&bg_ref);
-            return rc;
-        }
-
-        allocated_block =
-                ext4_fs_index_in_group2_baddr(sb, index_in_group,
-                        block_group);
-
-        goto success;
-    }
-
-    uint32_t blocks_in_group =
-            ext4_blocks_in_group_cnt(sb, block_group);
-
-    uint32_t end_idx = (index_in_group + 63) & ~63;
-    if (end_idx > blocks_in_group)
-        end_idx = blocks_in_group;
-
-    /* Try to find free block near to goal */
-    uint32_t tmp_idx;
-    for (tmp_idx = index_in_group + 1; tmp_idx < end_idx;
-            ++tmp_idx) {
-        if (ext4_bmap_is_bit_clr(bitmap_block.data, tmp_idx)) {
-            ext4_bmap_bit_set(bitmap_block.data, tmp_idx);
-
-            bitmap_block.dirty = true;
-            rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
-            if (rc != EOK)
-                return rc;
-
-            allocated_block =
-                    ext4_fs_index_in_group2_baddr(sb, tmp_idx,
-                            block_group);
-
-            goto success;
-        }
-    }
-
-
-
-    /* Find free bit in bitmap */
-    rc = ext4_bmap_bit_find_clr(bitmap_block.data,
-            index_in_group, blocks_in_group, &rel_block_idx);
-    if (rc == EOK) {
-        ext4_bmap_bit_set(bitmap_block.data, rel_block_idx);
-        bitmap_block.dirty = true;
-        rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
-        if (rc != EOK)
-            return rc;
-
-        allocated_block =
-                ext4_fs_index_in_group2_baddr(sb, rel_block_idx,
-                        block_group);
-
-        goto success;
-    }
-
-    /* No free block found yet */
-    ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
-    ext4_fs_put_block_group_ref(&bg_ref);
-
-    /* Try other block groups */
-    uint32_t block_group_count = ext4_block_group_cnt(sb);
-
-    uint32_t bgid = (block_group + 1) % block_group_count;
-    uint32_t count = block_group_count;
-
-    while (count > 0) {
-        rc = ext4_fs_get_block_group_ref(inode_ref->fs, bgid,
-                &bg_ref);
-        if (rc != EOK)
-            return rc;
-
-        /* Load block with bitmap */
-        bitmap_block_addr =
-                ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
-
-        rc = ext4_block_get(inode_ref->fs->bdev, &bitmap_block,
-                bitmap_block_addr);
-
-        if (rc != EOK) {
-            ext4_fs_put_block_group_ref(&bg_ref);
-            return rc;
-        }
-
-        /* Compute indexes */
-        first_in_group =
-                ext4_balloc_get_first_data_block_in_group(sb, &bg_ref);
-        index_in_group =
-                ext4_fs_baddr2_index_in_group(sb, first_in_group);
-        blocks_in_group = ext4_blocks_in_group_cnt(sb, bgid);
-
-        first_in_group_index =
-                ext4_fs_baddr2_index_in_group(sb, first_in_group);
-
-        if (index_in_group < first_in_group_index)
-            index_in_group = first_in_group_index;
-
-
-        rc = ext4_bmap_bit_find_clr(bitmap_block.data,
-                index_in_group, blocks_in_group, &rel_block_idx);
-
-        if (rc == EOK) {
-
-            ext4_bmap_bit_set(bitmap_block.data, rel_block_idx);
-
-            bitmap_block.dirty = true;
-            rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
-            if (rc != EOK)
-                return rc;
-
-            allocated_block =
-                    ext4_fs_index_in_group2_baddr(sb, rel_block_idx,
-                            bgid);
-
-            goto success;
-        }
-
-        ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
-        ext4_fs_put_block_group_ref(&bg_ref);
-
-        /* Goto next group */
-        bgid = (bgid + 1) % block_group_count;
-        count--;
-    }
-
-    return ENOSPC;
-
-    success:
-    /* Empty command - because of syntax */
-    ;
-
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-
-    /* Update superblock free blocks count */
-    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);
-    sb_free_blocks--;
-    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
-
-    /* Update inode blocks (different block size!) count */
-    uint64_t ino_blocks =
-            ext4_inode_get_blocks_count(sb, inode_ref->inode);
-    ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
-    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
-    inode_ref->dirty = true;
-
-    /* Update block group free blocks count */
-    uint32_t bg_free_blocks =
-            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
-    bg_free_blocks--;
-    ext4_bg_set_free_blocks_count(bg_ref.block_group, sb,
-        bg_free_blocks);
-
-    bg_ref.dirty = true;
-
-    ext4_fs_put_block_group_ref(&bg_ref);
-
-    *fblock = allocated_block;
-    return EOK;
-}
-
-int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,
-    uint32_t baddr, bool *free)
-{
-    int rc = EOK;
-
-    struct ext4_fs *fs = inode_ref->fs;
-    struct ext4_sblock *sb = &fs->sb;
-
-    /* Compute indexes */
-    uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, baddr);
-    uint32_t index_in_group =
-            ext4_fs_baddr2_index_in_group(sb, baddr);
-
-    /* Load block group reference */
-    struct ext4_block_group_ref bg_ref;
-    rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    /* Load block with bitmap */
-    uint32_t bitmap_block_addr =
-            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
-
-
-    struct	ext4_block bitmap_block;
-
-    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Check if block is free */
-    *free = ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group);
-
-    /* Allocate block if possible */
-    if (*free) {
-        ext4_bmap_bit_set(bitmap_block.data, index_in_group);
-        bitmap_block.dirty = true;
-    }
-
-    /* Release block with bitmap */
-    rc = ext4_block_set(fs->bdev, &bitmap_block);
-    if (rc != EOK) {
-        /* Error in saving bitmap */
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
-
-    /* If block is not free, return */
-    if (!(*free))
-        goto terminate;
-
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-
-    /* Update superblock free blocks count */
-    uint64_t sb_free_blocks = ext4_sb_get_free_blocks_cnt(sb);
-    sb_free_blocks--;
-    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
-
-    /* Update inode blocks count */
-    uint64_t ino_blocks =
-            ext4_inode_get_blocks_count(sb, inode_ref->inode);
-    ino_blocks += block_size / EXT4_INODE_BLOCK_SIZE;
-    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
-    inode_ref->dirty = true;
-
-    /* Update block group free blocks count */
-    uint32_t free_blocks =
-            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
-    free_blocks--;
-    ext4_bg_set_free_blocks_count(bg_ref.block_group,
-        sb, free_blocks);
-
-    bg_ref.dirty = true;
-
-    terminate:
-    return ext4_fs_put_block_group_ref(&bg_ref);
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_balloc.h
+++ /dev/null
@@ -1,93 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_balloc.h
- * @brief Physical block allocator.
- */
-
-#ifndef EXT4_BALLOC_H_
-#define EXT4_BALLOC_H_
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-
-
-/**@brief	Get first datablock in block group
- * @param	s superblock descriptor
- * @param	bg_ref block group reference
- * @return	block id of the first datablock in block group*/
-uint32_t ext4_balloc_get_first_data_block_in_group(struct ext4_sblock *s,
-         struct ext4_block_group_ref * bg_ref);
-
-/**@brief	Free block from inode.
- * @param	inode_ref inode reference
- * @param	baddr block address
- * @return 	standard error code*/
-int 	ext4_balloc_free_block(struct ext4_inode_ref *inode_ref,
-        uint32_t baddr);
-
-/**@brief	Free blocks from inode.
- * @param	inode_ref inode reference
- * @param	baddr block address
- * @return 	standard error code*/
-int 	ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref,
-        uint32_t first, uint32_t count);
-
-/**@brief	Allocate block procedure.
- * @param	inode_ref inode reference
- * @param	baddr allocated block address
- * @return 	standard error code*/
-int 	ext4_balloc_alloc_block(struct ext4_inode_ref *inode_ref,
-        uint32_t *baddr);
-
-/**@brief	Try allocate selected block.
- * @param	inode_ref inode reference
- * @param	baddr block address to allocate
- * @param	free if baddr is not allocated
- * @return 	standard error code*/
-int 	ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,
-        uint32_t baddr, bool *free);
-
-#endif /* EXT4_BALLOC_H_ */
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_bcache.c
+++ /dev/null
@@ -1,276 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_bcache.c
- * @brief Block cache allocator.
- */
-
-#include <ext4_config.h>
-#include <ext4_bcache.h>
-#include <ext4_debug.h>
-#include <ext4_errno.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-
-int	ext4_bcache_init_dynamic(struct	ext4_bcache *bc, uint32_t cnt,
-    uint32_t itemsize)
-{
-    ext4_assert(bc && cnt && itemsize);
-
-    bc->lru_ctr= 0;
-
-    bc->refctr	 	= 0;
-    bc->lru_id 		= 0;
-    bc->free_delay  = 0;
-    bc->lba	  	 	= 0;
-    bc->data	 	= 0;
-
-    bc->refctr   = malloc(cnt * sizeof(uint32_t));
-    if(!bc->refctr)
-        goto error;
-
-    bc->lru_id = malloc(cnt * sizeof(uint32_t));
-    if(!bc->lru_id)
-        goto error;
-
-    bc->free_delay = malloc(cnt * sizeof(uint8_t));
-    if(!bc->free_delay)
-        goto error;
-
-    bc->lba 	 = malloc(cnt * sizeof(uint64_t));
-    if(!bc->lba)
-        goto error;
-
-    bc->data	 = malloc(cnt * itemsize);
-    if(!bc->data)
-        goto error;
-
-    memset(bc->refctr, 0, cnt * sizeof(uint32_t));
-    memset(bc->lru_id, 0, cnt * sizeof(uint32_t));
-    memset(bc->free_delay, 0, cnt * sizeof(uint8_t));
-    memset(bc->lba, 0, cnt * sizeof(uint64_t));
-
-    bc->cnt      = cnt;
-    bc->itemsize = itemsize;
-    bc->ref_blocks = 0;
-    bc->max_ref_blocks = 0;
-
-    return EOK;
-
-    error:
-
-    if(bc->refctr)
-        free(bc->refctr);
-
-    if(bc->lru_id)
-        free(bc->lru_id);
-
-    if(bc->free_delay)
-        free(bc->free_delay);
-
-    if(bc->lba)
-        free(bc->lba);
-
-    if(bc->data)
-        free(bc->data);
-
-    return ENOMEM;
-}
-
-int ext4_bcache_fini_dynamic(struct	ext4_bcache *bc)
-{
-    if(bc->refctr)
-        free(bc->refctr);
-
-    if(bc->lru_id)
-        free(bc->lru_id);
-
-    if(bc->free_delay)
-        free(bc->free_delay);
-
-    if(bc->lba)
-        free(bc->lba);
-
-    if(bc->data)
-        free(bc->data);
-
-    bc->lru_ctr= 0;
-
-    bc->refctr	 	= 0;
-    bc->lru_id 		= 0;
-    bc->free_delay  = 0;
-    bc->lba	  	 	= 0;
-    bc->data	 	= 0;
-
-    return EOK;
-}
-
-
-int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,
-    bool *is_new)
-{
-    uint32_t i;
-    ext4_assert(bc && b && is_new);
-
-    /*Check if valid.*/
-    ext4_assert(b->lb_id);
-    if(!b->lb_id){
-        ext4_assert(b->lb_id);
-    }
-
-    uint32_t cache_id = bc->cnt;
-    uint32_t alloc_id;
-
-    *is_new = false;
-
-    /*Find in free blocks (Last Recently Used).*/
-    for (i = 0; i < bc->cnt; ++i) {
-
-        /*Check if block is already in cache*/
-        if(b->lb_id == bc->lba[i]){
-
-            if(!bc->refctr[i] && !bc->free_delay[i])
-                bc->ref_blocks++;
-
-            /*Update reference counter*/
-            bc->refctr[i]++;
-
-            /*Update usage marker*/
-            bc->lru_id[i] = ++bc->lru_ctr;
-
-            /*Set valid cache data and id*/
-            b->data = bc->data + i * bc->itemsize;
-            b->cache_id = i;
-
-            return EOK;
-        }
-
-        /*Best fit calculations.*/
-        if(bc->refctr[i])
-            continue;
-
-        if(bc->free_delay[i])
-            continue;
-
-        /*Block is unreferenced, but it may exist block with
-         * lower usage marker*/
-
-        /*First find.*/
-        if(cache_id == bc->cnt){
-            cache_id = i;
-            alloc_id = bc->lru_id[i];
-            continue;
-        }
-
-        /*Next find*/
-        if(alloc_id <= bc->lru_id[i])
-            continue;
-
-        /*This block has lower alloc id marker*/
-        cache_id = i;
-        alloc_id = bc->lru_id[i];
-    }
-
-
-    if(cache_id != bc->cnt){
-        /*There was unreferenced block*/
-        bc->lba[cache_id] 	   = b->lb_id;
-        bc->refctr[cache_id]   = 1;
-        bc->lru_id[cache_id] = ++bc->lru_ctr;
-
-        /*Set valid cache data and id*/
-        b->data = bc->data + cache_id * bc->itemsize;
-        b->cache_id = cache_id;
-
-        /*Statistics*/
-        bc->ref_blocks++;
-        if(bc->ref_blocks > bc->max_ref_blocks)
-            bc->max_ref_blocks = bc->ref_blocks;
-
-
-        /*Block needs to be read.*/
-        *is_new = true;
-
-        return EOK;
-    }
-
-    ext4_dprintf(EXT4_DEBUG_BCACHE,
-        "ext4_bcache_alloc: FAIL, unable to alloc block cache!\n");
-    return ENOMEM;
-}
-
-int ext4_bcache_free (struct ext4_bcache *bc, struct ext4_block *b,
-    uint8_t free_delay)
-{
-    ext4_assert(bc && b);
-
-    /*Check if valid.*/
-    ext4_assert(b->lb_id);
-
-    /*Block should be in cache.*/
-    ext4_assert(b->cache_id < bc->cnt);
-
-    /*Check if someone don't try free unreferenced block cache.*/
-    ext4_assert(bc->refctr[b->cache_id]);
-
-    /*Just decrease reference counter*/
-    if(bc->refctr[b->cache_id])
-        bc->refctr[b->cache_id]--;
-
-    if(free_delay)
-        bc->free_delay[b->cache_id] = free_delay;
-
-    /*Update statistics*/
-    if(!bc->refctr[b->cache_id] && !bc->free_delay[b->cache_id])
-        bc->ref_blocks--;
-
-    b->lb_id    = 0;
-    b->data     = 0;
-    b->cache_id = 0;
-
-    return EOK;
-}
-
-
-
-bool ext4_bcache_is_full(struct ext4_bcache *bc)
-{
-    return (bc->cnt == bc->ref_blocks);
-}
-
-/**
- * @}
- */
-
-
--- a/src/lwext4/ext4_bcache.h
+++ /dev/null
@@ -1,155 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_bcache.h
- * @brief Block cache allocator.
- */
-
-#ifndef EXT4_BCACHE_H_
-#define EXT4_BCACHE_H_
-
-#include <ext4_config.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-
-/**@brief	Single block descriptor.*/
-struct	ext4_block {
-    /**@brief	Dirty flag.*/
-    bool		dirty;
-
-    /**@brief	Logical block ID*/
-    uint64_t	lb_id;
-
-    /**@brief   Cache id*/
-    uint32_t    cache_id;
-
-    /**@brief	Data buffer.*/
-    uint8_t		*data;
-};
-
-
-/**@brief	Block cache descriptor.*/
-struct	ext4_bcache {
-
-    /**@brief	Item count in block cache*/
-    uint32_t	cnt;
-
-    /**@brief	Item size in block cache*/
-    uint32_t	itemsize;
-
-    /**@brief	Last recently used counter.*/
-    uint32_t	lru_ctr;
-
-    /**@brief	Reference count table (cnt).*/
-    uint32_t	*refctr;
-
-    /**@brief	Last recently used ID table (cnt)*/
-    uint32_t 	*lru_id;
-
-    /**@brief	Free delay mode table (cnt)*/
-    uint8_t 	*free_delay;
-
-    /**@brief	Logical block table (cnt).*/
-    uint64_t	*lba;
-
-    /**@brief	Cache data buffers (cnt * itemsize)*/
-    uint8_t		*data;
-
-    /**@brief	Currently referenced datablocks*/
-    uint32_t	ref_blocks;
-
-    /**@brief	Maximum referenced datablocks*/
-    uint32_t	max_ref_blocks;
-
-};
-
-/**@brief	Static initializer of block cache structure.*/
-#define EXT4_BCACHE_STATIC_INSTANCE(__name, __cnt, __itemsize)      \
-        static uint32_t	__name##_refctr[(__cnt)];                   \
-        static uint32_t	__name##_lru_id[(__cnt)];                   \
-        static uint8_t		__name##_free_delay[(__cnt)];           \
-        static uint64_t	__name##_lba[(__cnt)];                      \
-        static uint8_t 	__name##_data[(__cnt) * (__itemsize)];      \
-        static struct ext4_bcache	__name = {                      \
-                .cnt 	   = __cnt,                                 \
-                .itemsize  = __itemsize,                            \
-                .lru_ctr   = 0,                                     \
-                .refctr	   = __name##_refctr,                       \
-                .lru_id    = __name##_lru_id,                       \
-                .lba	   = __name##_lba,                          \
-                .free_delay= __name##_free_delay,                   \
-                .data	   = __name##_data,                         \
-        }
-
-
-/**@brief	Dynamic initialization of block cache.
- * @param	bc block cache descriptor
- * @param	cnt items count in block cache
- * @param	itemsize single item size (in bytes)
- * @return	standard error code*/
-int	ext4_bcache_init_dynamic(struct	ext4_bcache *bc, uint32_t cnt,
-    uint32_t itemsize);
-
-/**@brief	Dynamic de-initialization of block cache.
- * @param	bc block cache descriptor
- * @return	standard error code*/
-int ext4_bcache_fini_dynamic(struct	ext4_bcache *bc);
-
-/**@brief	Allocate block from block cache memory.
- *          Unreferenced block allocation is based on LRU
- *          (Last Recently Used) algorithm.
- * @param 	bc	block cache descriptor
- * @param	b block to alloc
- * @param	is_new block is new (needs to be read)
- * @return  standard error code*/
-int ext4_bcache_alloc(struct ext4_bcache *bc, struct ext4_block *b,
-    bool *is_new);
-
-/**@brief	Free block from cache memory (decrement reference counter).
- * @param 	bc	block cache descriptor
- * @param	b block to free
- * @return  standard error code*/
-int ext4_bcache_free (struct ext4_bcache *bc, struct ext4_block *b,
-    uint8_t free_delay);
-
-
-/**@brief	Return a full status of block cache.
- * @param 	bc	block cache descriptor
- * @return	full status*/
-bool ext4_bcache_is_full(struct ext4_bcache *bc);
-
-#endif /* EXT4_BCACHE_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_bitmap.c
+++ /dev/null
@@ -1,173 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_bitmap.c
- * @brief Block/inode bitmap allocator.
- */
-
-#include <ext4_config.h>
-#include <ext4_bitmap.h>
-
-#include <ext4_errno.h>
-
-
-void ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt)
-{
-    uint32_t i;
-
-    i = sbit;
-
-    while(i & 7){
-
-        if(!bcnt)
-            return;
-
-        ext4_bmap_bit_clr(bmap, i);
-
-        bcnt--;
-        i++;
-    }
-
-    sbit  = i;
-    bmap += (sbit >> 3);
-
-
-
-    while(bcnt >= 32){
-        *(uint32_t *)bmap = 0;
-
-        bmap += 4;
-        bcnt -= 32;
-        sbit += 32;
-    }
-
-    while(bcnt >= 16){
-        *(uint16_t *)bmap = 0;
-
-        bmap += 2;
-        bcnt -= 16;
-        sbit += 16;
-    }
-
-    while(bcnt >= 8){
-        *bmap = 0;
-
-        bmap += 1;
-        bcnt -= 8;
-        sbit += 8;
-    }
-
-    for (i = 0; i < bcnt; ++i) {
-        ext4_bmap_bit_clr(bmap, i);
-    }
-}
-
-
-
-int ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit,
-    uint32_t *bit_id)
-{
-    uint32_t i;
-    uint32_t bcnt = ebit - sbit;
-
-    i = sbit;
-
-    while(i & 7){
-
-        if(!bcnt)
-            return ENOSPC;
-
-        if(ext4_bmap_is_bit_clr(bmap, i)){
-            *bit_id = sbit;
-            return EOK;
-        }
-
-        i++;
-        bcnt--;
-    }
-
-    sbit  = i;
-    bmap += (sbit >> 3);
-
-
-    while(bcnt >= 32){
-        if(*(uint32_t *)bmap != 0xFFFFFFFF)
-            goto finish_it;
-
-
-        bmap += 4;
-        bcnt -= 32;
-        sbit += 32;
-    }
-
-    while(bcnt >= 16){
-        if(*(uint16_t *)bmap != 0xFFFF)
-            goto finish_it;
-
-
-        bmap += 2;
-        bcnt -= 16;
-        sbit += 16;
-    }
-
-    finish_it:
-    while(bcnt >= 8){
-        if(*bmap != 0xFF){
-            for (i = 0; i < 8; ++i) {
-                if(ext4_bmap_is_bit_clr(bmap, i)){
-                    *bit_id = sbit + i;
-                    return EOK;
-                }
-            }
-        }
-
-        bmap += 1;
-        bcnt -= 8;
-        sbit += 8;
-    }
-
-    for (i = 0; i < bcnt; ++i) {
-        if(ext4_bmap_is_bit_clr(bmap, i)){
-            *bit_id = sbit + i;
-            return EOK;
-        }
-    }
-
-
-    return ENOSPC;
-}
-
-/**
- * @}
- */
-
-
--- a/src/lwext4/ext4_bitmap.h
+++ /dev/null
@@ -1,98 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_bitmap.h
- * @brief Block/inode bitmap allocator.
- */
-
-
-#ifndef EXT4_BITMAP_H_
-#define EXT4_BITMAP_H_
-
-#include <ext4_config.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-/**@brief	Set bitmap bit.
- * @param	bmap bitmap
- * @param	bit	 bit to set*/
-static inline void ext4_bmap_bit_set(uint8_t *bmap, uint32_t bit)
-{
-    *(bmap + (bit >> 3)) |= (1 << (bit & 7));
-}
-
-/**@brief	Clear bitmap bit.
- * @param	bmap bitmap buffer
- * @param	bit	 bit to clear*/
-static inline void ext4_bmap_bit_clr(uint8_t *bmap, uint32_t bit)
-{
-    *(bmap + (bit >> 3)) &= ~(1 << (bit & 7));
-}
-
-
-/**@brief	Check if the bitmap bit is set.
- * @param	bmap bitmap buffer
- * @param	bit	 bit to check*/
-static inline bool ext4_bmap_is_bit_set(uint8_t *bmap, uint32_t bit)
-{
-    return (*(bmap + (bit >> 3)) & (1 << (bit & 7)));
-}
-
-/**@brief	Check if the bitmap bit is clear.
- * @param	bmap bitmap buffer
- * @param	bit	 bit to check*/
-static inline bool ext4_bmap_is_bit_clr(uint8_t *bmap, uint32_t bit)
-{
-    return !ext4_bmap_is_bit_set(bmap, bit);
-}
-
-/**@brief	Free range of bits in bitmap.
- * @param	bmap bitmap buffer
- * @param	sbit start bit
- * @param	bcnt bit count*/
-void ext4_bmap_bits_free(uint8_t *bmap, uint32_t sbit, uint32_t bcnt);
-
-/**@brief	Find first clear bit in bitmap.
- * @param	sbit start bit of search
- * @param	ebit end bit of search
- * @param	bit_id output parameter (first free bit)
- * @return	standard error code*/
-int ext4_bmap_bit_find_clr(uint8_t *bmap, uint32_t sbit, uint32_t ebit,
-    uint32_t *bit_id);
-
-
-#endif /* EXT4_BITMAP_H_ */
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_block_group.c
+++ /dev/null
@@ -1,55 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_block_group.c
- * @brief Block group function set.
- */
-
-#include <ext4_config.h>
-#include <ext4_block_group.h>
-
-
-
-uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len)
-{
-    // TODO
-    return 0;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_block_group.h
+++ /dev/null
@@ -1,199 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_block_group.h
- * @brief Block group function set.
- */
-
-#ifndef EXT4_BLOCK_GROUP_H_
-#define EXT4_BLOCK_GROUP_H_
-
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-#include <ext4_super.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-
-static inline uint64_t ext4_bg_get_block_bitmap(struct ext4_bgroup *bg,
-    struct ext4_sblock *s)
-{
-    uint64_t v = to_le32(bg->block_bitmap_lo);
-
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint64_t) to_le32(bg->block_bitmap_hi) << 32;
-
-    return v;
-}
-
-static inline uint64_t ext4_bg_get_inode_bitmap(struct ext4_bgroup *bg,
-    struct ext4_sblock *s)
-{
-
-    uint64_t v = to_le32(bg->inode_bitmap_lo);
-
-    if (ext4_sb_get_desc_size(s)> EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint64_t) to_le32(bg->inode_bitmap_hi) << 32;
-
-    return v;
-}
-
-static inline uint64_t ext4_bg_get_inode_table_first_block(
-    struct ext4_bgroup *bg, struct ext4_sblock *s)
-{
-    uint64_t v = to_le32(bg->inode_table_first_block_lo);
-
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint64_t) to_le32(bg->inode_table_first_block_hi) << 32;
-
-    return v;
-}
-
-static inline uint32_t ext4_bg_get_free_blocks_count(struct ext4_bgroup *bg,
-    struct ext4_sblock *s)
-{
-    uint32_t v = to_le16(bg->free_blocks_count_lo);
-
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint32_t) to_le16(bg->free_blocks_count_hi) << 16;
-
-    return v;
-}
-
-static inline void 	 ext4_bg_set_free_blocks_count(struct ext4_bgroup *bg,
-    struct ext4_sblock *s, uint32_t cnt)
-{
-    bg->free_blocks_count_lo = to_le16((cnt << 16) >> 16);
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        bg->free_blocks_count_hi = to_le16(cnt >> 16);
-}
-
-static inline uint32_t ext4_bg_get_free_inodes_count(struct ext4_bgroup *bg,
-    struct ext4_sblock *s)
-{
-    uint32_t v = to_le16(bg->free_inodes_count_lo);
-
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint32_t) to_le16(bg->free_inodes_count_hi) << 16;
-
-    return v;
-}
-
-static inline void 	 ext4_bg_set_free_inodes_count(struct ext4_bgroup *bg,
-    struct ext4_sblock *s, uint32_t cnt)
-{
-    bg->free_inodes_count_lo = to_le16((cnt << 16) >> 16);
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        bg->free_inodes_count_hi = to_le16(cnt >> 16);
-}
-
-
-static inline uint32_t ext4_bg_get_used_dirs_count(struct ext4_bgroup *bg,
-    struct ext4_sblock *s)
-{
-    uint32_t v = to_le16(bg->used_dirs_count_lo);
-
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint32_t) to_le16(bg->used_dirs_count_hi) << 16;
-
-    return v;
-}
-
-static inline void 	 ext4_bg_set_used_dirs_count(struct ext4_bgroup *bg,
-    struct ext4_sblock *s, uint32_t cnt)
-{
-    bg->used_dirs_count_lo = to_le16((cnt << 16) >> 16);
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        bg->used_dirs_count_hi = to_le16(cnt >> 16);
-}
-
-
-static inline uint32_t ext4_bg_get_itable_unused(struct ext4_bgroup *bg,
-    struct ext4_sblock *s)
-{
-
-    uint32_t v = to_le16(bg->itable_unused_lo);
-
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        v |= (uint32_t) to_le16(bg->itable_unused_hi) << 16;
-
-    return v;
-}
-
-static inline void 	 ext4_bg_set_itable_unused(struct ext4_bgroup *bg,
-    struct ext4_sblock *s, uint32_t cnt)
-{
-    bg->itable_unused_lo = to_le16((cnt << 16) >> 16);
-    if (ext4_sb_get_desc_size(s) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        bg->itable_unused_hi = to_le16(cnt >> 16);
-}
-
-
-static inline void 	 ext4_bg_set_checksum(struct ext4_bgroup *bg,
-    uint16_t crc)
-{
-    bg->checksum = to_le16(crc);
-}
-
-static inline bool 	 ext4_bg_has_flag(struct ext4_bgroup *bg, uint32_t f)
-{
-    return to_le16(bg->flags) & f;
-}
-
-static inline void 	 ext4_bg_set_flag(struct ext4_bgroup *bg, uint32_t f)
-{
-    uint16_t flags = to_le16(bg->flags);
-    flags |= f;
-    bg->flags = to_le16(flags);
-}
-
-static inline void 	 ext4_bg_clear_flag(struct ext4_bgroup *bg, uint32_t f)
-{
-    uint16_t flags = to_le16(bg->flags);
-    flags &= ~f;
-    bg->flags = to_le16(flags);
-}
-
-
-uint16_t ext4_bg_crc16(uint16_t crc, const uint8_t *buffer, size_t len);
-
-#endif /* EXT4_BLOCK_GROUP_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_blockdev.c
+++ /dev/null
@@ -1,448 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_blockdev.c
- * @brief Block device module.
- */
-
-#include <ext4_config.h>
-#include <ext4_blockdev.h>
-#include <ext4_errno.h>
-#include <ext4_debug.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-
-
-int	ext4_block_init(struct	ext4_blockdev *bdev)
-{
-    int rc;
-    ext4_assert(bdev);
-
-    ext4_assert(bdev->open && bdev->close && bdev->bread  && bdev->bwrite);
-
-    /*Low level block init*/
-    rc = bdev->open(bdev);
-    if(EOK != rc)
-        return rc;
-
-    bdev->flags |= EXT4_BDEV_INITIALIZED;
-
-    return	EOK;
-}
-
-int ext4_block_bind_bcache(struct ext4_blockdev *bdev, struct ext4_bcache *bc)
-{
-    ext4_assert(bdev && bc);
-    bdev->bc = bc;
-    return EOK;
-}
-
-void ext4_block_set_lb_size(struct	ext4_blockdev *bdev, uint64_t	lb_bsize)
-{
-    /*Logical block size has to be multiply of physical */
-    ext4_assert(!(lb_bsize % bdev->ph_bsize));
-
-    bdev->lg_bsize = lb_bsize;
-    bdev->lg_bcnt = (bdev->ph_bcnt * bdev->ph_bsize) / lb_bsize;
-
-}
-
-int ext4_block_fini(struct	ext4_blockdev *bdev)
-{
-    ext4_assert(bdev);
-
-    bdev->flags &= ~(EXT4_BDEV_INITIALIZED);
-
-    /*Low level block fini*/
-    return bdev->close(bdev);
-}
-
-
-int ext4_block_get(struct	ext4_blockdev *bdev, struct	ext4_block *b,
-    uint64_t lba)
-{
-    uint64_t pba;
-    uint32_t pb_cnt;
-    bool	 is_new;
-    int 	 r;
-    ext4_assert(bdev && b);
-
-    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
-        return EIO;
-
-    if(!(lba < bdev->lg_bcnt))
-        return ERANGE;
-
-    b->dirty = 0;
-    b->lb_id = lba;
-
-    r = ext4_bcache_alloc(bdev->bc, b, &is_new);
-    if(r != EOK)
-        return r;
-
-
-    if(!is_new){
-        /*Block is in cache. Read from physical device is not required*/
-        return EOK;
-    }
-
-    if(!b->data)
-        return ENOMEM;
-
-    pba 	= (lba * bdev->lg_bsize) / bdev->ph_bsize;
-    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
-
-
-    r = bdev->bread(bdev, b->data, pba, pb_cnt);
-
-    if(r != EOK){
-        ext4_bcache_free(bdev->bc, b, 0);
-        b->lb_id = 0;
-        return r;
-    }
-
-    bdev->bread_ctr++;
-
-    return EOK;
-}
-
-int ext4_block_set(struct	ext4_blockdev *bdev, struct	ext4_block *b)
-{
-    uint64_t pba;
-    uint32_t pb_cnt;
-    uint32_t i;
-    int r;
-
-    ext4_assert(bdev && b);
-
-    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
-        return EIO;
-
-    /*Doesn,t need to write.*/
-    if(b->dirty == false){
-        ext4_bcache_free(bdev->bc, b, 0);
-        return EOK;
-    }
-
-    /*Free cache delay mode*/
-    if(bdev->cache_flush_delay){
-
-        /*Free cahe block and mark as free delayed*/
-        ext4_bcache_free(bdev->bc, b, bdev->cache_flush_delay);
-
-        /*If cache is full we have to flush it anyway :(*/
-        if(ext4_bcache_is_full(bdev->bc)){
-            for (i = 0; i < bdev->bc->cnt; ++i) {
-                /*Check if buffer free was delayed.*/
-                if(!bdev->bc->free_delay[i])
-                    continue;
-
-                /*Check reference counter.*/
-                if(bdev->bc->refctr[i])
-                    continue;
-
-                /*Buffer free was delayed and have no reference. Flush it.*/
-                r = ext4_block_set_direct(bdev,
-                        bdev->bc->data + bdev->bc->itemsize * i,
-                        bdev->bc->lba[i]);
-                if(r != EOK)
-                    return r;
-
-                /*No delayed anymore*/
-                bdev->bc->free_delay[i] = 0;
-
-                /*Reduce refered block count*/
-                bdev->bc->ref_blocks--;
-            }
-        }
-
-        return EOK;
-    }
-
-    pba 	= (b->lb_id * bdev->lg_bsize) / bdev->ph_bsize;
-    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
-
-
-    r = bdev->bwrite(bdev, b->data, pba, pb_cnt);
-
-    if(r != EOK){
-        b->dirty = false;
-        ext4_bcache_free(bdev->bc, b, 0);
-        return r;
-    }
-
-    bdev->bwrite_ctr++;
-    b->dirty = false;
-    ext4_bcache_free(bdev->bc, b, 0);
-    return EOK;
-}
-
-int ext4_block_get_direct(struct	ext4_blockdev *bdev, void *buf,
-    uint64_t lba)
-{
-    uint64_t pba;
-    uint32_t pb_cnt;
-
-    ext4_assert(bdev && buf);
-
-    pba 	= (lba * bdev->lg_bsize) / bdev->ph_bsize;
-    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
-
-    bdev->bread_ctr++;
-
-    return bdev->bread(bdev, buf, pba, pb_cnt);
-}
-
-
-
-int ext4_block_set_direct(struct	ext4_blockdev *bdev, const void *buf,
-    uint64_t lba)
-{
-    uint64_t pba;
-    uint32_t pb_cnt;
-
-    ext4_assert(bdev && buf);
-
-    pba 	= (lba * bdev->lg_bsize) / bdev->ph_bsize;
-    pb_cnt  =  bdev->lg_bsize / bdev->ph_bsize;
-
-    bdev->bwrite_ctr++;
-
-    return bdev->bwrite(bdev, buf, pba, pb_cnt);
-}
-
-
-int	ext4_block_writebytes(struct	ext4_blockdev *bdev, uint64_t off,
-    const void *buf, uint32_t len)
-{
-    uint64_t block_idx;
-    uint64_t block_end;
-
-    uint32_t blen;
-
-    uint32_t unalg;
-    int		 r = EOK;
-
-    const uint8_t	*p = (void *)buf;
-
-    ext4_assert(bdev && buf);
-
-    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
-        return EIO;
-
-
-    block_idx =  off / bdev->ph_bsize;
-    block_end   =  block_idx + len / bdev->ph_bsize;
-
-    if(!(block_end < bdev->ph_bcnt))
-        return EINVAL;				/*Ups. Out of range operation*/
-
-
-    /*OK lets deal with the first possible unaligned block*/
-    unalg = (off & (bdev->ph_bsize - 1));
-    if(unalg){
-
-        uint32_t wlen = (bdev->ph_bsize - unalg) > len ?
-                len : (bdev->ph_bsize - unalg);
-
-        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
-
-        if(r != EOK)
-            return r;
-
-        memcpy(bdev->ph_bbuf + unalg, p, wlen);
-
-        r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1);
-
-        if(r != EOK)
-            return r;
-
-        p   += wlen;
-        len -= wlen;
-        block_idx++;
-    }
-
-
-    /*Aligned data*/
-    blen = len / bdev->ph_bsize;
-
-    r = bdev->bwrite(bdev, p, block_idx, blen);
-
-    if(r != EOK)
-        return r;
-
-    p 	+= bdev->ph_bsize * blen;
-    len -= bdev->ph_bsize * blen;
-
-    block_idx += blen;
-
-
-    /*Rest of the data*/
-    if(len){
-
-        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
-
-        if(r != EOK)
-            return r;
-
-        memcpy(bdev->ph_bbuf, p, len);
-
-        r = bdev->bwrite(bdev, bdev->ph_bbuf, block_idx, 1);
-
-        if(r != EOK)
-            return r;
-    }
-
-    return r;
-}
-
-
-
-
-int ext4_block_readbytes(struct	ext4_blockdev *bdev, uint64_t off, void *buf,
-    uint32_t len)
-{
-
-    uint64_t block_idx;
-    uint64_t block_end;
-    uint32_t blen;
-
-    uint32_t unalg;
-    int		 r = EOK;
-
-    uint8_t	*p = (void *)buf;
-
-    ext4_assert(bdev && buf);
-
-    if(!(bdev->flags & EXT4_BDEV_INITIALIZED))
-        return EIO;
-
-
-    block_idx =  off / bdev->ph_bsize;
-    block_end   =  block_idx + len / bdev->ph_bsize;
-
-    if(!(block_end < bdev->ph_bcnt))
-        return EINVAL;				/*Ups. Out of range operation*/
-
-
-    /*OK lets deal with the first possible unaligned block*/
-    unalg = (off & (bdev->ph_bsize - 1));
-    if(unalg){
-
-        uint32_t rlen = (bdev->ph_bsize - unalg) > len ?
-                len : (bdev->ph_bsize - unalg);
-
-        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
-
-        if(r != EOK)
-            return r;
-
-        memcpy(p, bdev->ph_bbuf + unalg, rlen);
-
-        p   += rlen;
-        len -= rlen;
-        block_idx++;
-    }
-
-
-    /*Aligned data*/
-    blen = len / bdev->ph_bsize;
-
-    r = bdev->bread(bdev, p, block_idx, blen);
-
-    if(r != EOK)
-        return r;
-
-    p 	+= bdev->ph_bsize * blen;
-    len -= bdev->ph_bsize * blen;
-
-    block_idx += blen;
-
-
-    /*Rest of the data*/
-    if(len){
-
-        r = bdev->bread(bdev, bdev->ph_bbuf, block_idx, 1);
-
-        if(r != EOK)
-            return r;
-
-        memcpy(p, bdev->ph_bbuf, len);
-
-    }
-
-    return r;
-}
-
-int 	ext4_block_delay_cache_flush(struct	ext4_blockdev *bdev,
-    uint8_t on_off)
-{
-    int r;
-    uint32_t i;
-    bdev->cache_flush_delay = on_off;
-
-    /*Flush all delayed cache blocks*/
-    if(!on_off){
-        for (i = 0; i < bdev->bc->cnt; ++i) {
-
-            /*Check if buffer free was delayed.*/
-            if(!bdev->bc->free_delay[i])
-                continue;
-
-            /*Check reference counter.*/
-            if(bdev->bc->refctr[i])
-                continue;
-
-            /*Buffer free was delayed and have no reference. Flush it.*/
-            r = ext4_block_set_direct(bdev,
-                    bdev->bc->data + bdev->bc->itemsize * i,
-                    bdev->bc->lba[i]);
-            if(r != EOK)
-                return r;
-
-            /*No delayed anymore*/
-            bdev->bc->free_delay[i] = 0;
-
-            /*Reduce refered block count*/
-            bdev->bc->ref_blocks--;
-        }
-    }
-
-    return EOK;
-}
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_blockdev.h
+++ /dev/null
@@ -1,211 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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.
- */
-#ifndef EXT4_BLOCKDEV_H_
-#define EXT4_BLOCKDEV_H_
-
-/** @addtogroup lwext4
- * @{
- */
-/**
- * @file  ext4_blockdev.h
- * @brief Block device module.
- */
-
-#include <ext4_config.h>
-#include <ext4_bcache.h>
-#include <ext4_debug.h>
-
-
-#include <stdbool.h>
-#include <stdint.h>
-
-/**@brief	Initialization status flag*/
-#define EXT4_BDEV_INITIALIZED			(1 << 0)
-
-
-/**@brief	Definiton of the simple block device.*/
-struct	ext4_blockdev  {
-
-    /**@brief	Open device function
-     * @param	bdev block device.*/
-    int			(*open)(struct	ext4_blockdev *bdev);
-
-    /**@brief	Block read function.
-     * @param	bdev block device
-     * @param	buf	output buffer
-     * @param	blk_id	block id
-     * @param	blk_cnt block count*/
-    int			(*bread)(struct	ext4_blockdev *bdev, void *buf,
-                uint64_t blk_id, uint32_t blk_cnt);
-
-    /**@brief	Block write function.
-     * @param	buf input buffer
-     * @param	blk_id block id
-     * @param	blk_cnt block count*/
-    int			(*bwrite)(struct	ext4_blockdev *bdev, const void *buf,
-                uint64_t blk_id, uint32_t blk_cnt);
-
-    /**@brief	Close device function.
-     * @param	bdev block device.*/
-    int			(*close)(struct	ext4_blockdev *bdev);
-
-    /**@brief	Block size (bytes): physical*/
-    uint32_t	ph_bsize;
-
-    /**@brief	Block count: physical.*/
-    uint64_t	ph_bcnt;
-
-    /**@brief	Block size buffer: physical.*/
-    uint8_t		*ph_bbuf;
-
-    /**@brief	Block size (bytes) logical*/
-    uint32_t	lg_bsize;
-
-    /**@brief	Block count: phisical.*/
-    uint64_t	lg_bcnt;
-
-    /**@brief	Flags of te block device.*/
-    uint8_t		flags;
-
-    /**@brief	Block cache.*/
-    struct	ext4_bcache *bc;
-
-    uint8_t		cache_flush_delay;
-
-    uint32_t	bread_ctr;
-    uint32_t	bwrite_ctr;
-};
-
-
-/**@brief	Static initialization fo the block device.*/
-#define EXT4_BLOCKDEV_STATIC_INSTANCE(__name, __bsize, __bcnt, __open,  \
-                                            __bread, __bwrite, __close)	\
-        static uint8_t	__name##_ph_bbuf[(__bsize)];                    \
-        static struct	ext4_blockdev __name = {                        \
-                .open   = __open,                                       \
-                .bread  = __bread,                                      \
-                .bwrite = __bwrite,                                     \
-                .close  = __close,                                      \
-                .ph_bsize  = __bsize,                                   \
-                .ph_bcnt   = __bcnt,                                    \
-                .ph_bbuf   = __name##_ph_bbuf,                          \
-        }
-
-/**@brief	Block device initialization.
- * @param	bdev block device descriptor
- * @param	bg_bsize logical block size
- * @param	bdev block device descriptor
- * @return 	standard error code*/
-int	ext4_block_init(struct	ext4_blockdev *bdev);
-
-
-/**@brief	Binds a bcache to block device.
- * @param	bdev block device descriptor
- * @param	bc block cache descriptor
- * @return 	standard error code*/
-int ext4_block_bind_bcache(struct ext4_blockdev *bdev,
-    struct ext4_bcache *bc);
-
-/**@brief	Close block device
- * @param	bdev block device descriptor
- * @return 	standard error code*/
-int ext4_block_fini(struct	ext4_blockdev *bdev);
-
-
-/**@brief	Set logical block size in block device.
- * @param	bdev block device descriptor
- * @param	lb_size ligical block size (in bytes)
- * @return 	standard error code*/
-void ext4_block_set_lb_size(struct	ext4_blockdev *bdev,
-    uint64_t lb_bsize);
-
-/**@brief	Block get function (through cache).
- * @param	bdev block device descriptor
- * @param	b block descriptor
- * @param	lba logical block address
- * @return 	standard error code*/
-int ext4_block_get(struct	ext4_blockdev *bdev, struct	ext4_block *b,
-    uint64_t lba);
-
-/**@brief	Block set procedure (through cache).
- * @param	bdev block device descriptor
- * @param	b block descriptor
- * @return 	standard error code*/
-int ext4_block_set(struct	ext4_blockdev *bdev, struct	ext4_block *b);
-
-
-/**@brief	Block read procedure (without cache)
- * @param	bdev block device descriptor
- * @param	buf output buffer
- * @param	lba logical block adderss
- * @return 	standard error code*/
-int ext4_block_get_direct(struct	ext4_blockdev *bdev, void *buf,
-    uint64_t lba);
-
-
-/**@brief	Block write procedure (without cache)
- * @param	bdev block device descriptor
- * @param	buf output buffer
- * @param	lba logical block address
- * @return 	standard error code*/
-int ext4_block_set_direct(struct	ext4_blockdev *bdev, const void *buf,
-    uint64_t lba);
-
-/**@brief	Write to block device (by direct adress).
- * @param	bdev block device descriptor
- * @param	off byte offset in block device
- * @param	buf input buffer
- * @param	len length of the write nuffer
- * @return 	EOK when sucess*/
-int	ext4_block_writebytes(struct	ext4_blockdev *bdev, uint64_t off,
-    const void *buf, uint32_t len);
-
-
-
-/**@brief	Read freom block device (by direct adress).
- * @param	bdev block device descriptor
- * @param	off byte offset in block device
- * @param	buf input buffer
- * @param	len length of the write nuffer
- * @return 	EOK when sucess*/
-int ext4_block_readbytes(struct	ext4_blockdev *bdev, uint64_t off,
-    void *buf, uint32_t len);
-
-/**@brief	Enable/disable delayed cache flush mode.
- * @param	bdev block device descriptor
- * @param	on_off
- * 				!0 	- ENABLE
- * 				 0	- DISABLE (all delayed cache buffers will be flushed)
- * @return	standard error code*/
-int ext4_block_delay_cache_flush(struct	ext4_blockdev *bdev, uint8_t on_off);
-
-#endif /* EXT4_BLOCKDEV_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_config.h
+++ /dev/null
@@ -1,99 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_config.h
- * @brief Configuration file.
- */
-
-#ifndef EXT4_CONFIG_H_
-#define EXT4_CONFIG_H_
-
-#ifdef CONFIG_HAVE_OWN_CFG
-#include <config.h>
-#endif
-
-
-/**@brief	Enable directory indexing feature (EXT3 feature)*/
-#ifndef CONFIG_DIR_INDEX_ENABLE
-#define CONFIG_DIR_INDEX_ENABLE				0
-#endif
-
-/**@brief	Enable extents feature (EXT4 feature)*/
-#ifndef CONFIG_EXTENT_ENABLE
-#define CONFIG_EXTENT_ENABLE				0
-#endif
-
-
-
-/**@brief	Include error codes from ext4_errno or sandard library.*/
-#ifndef CONFIG_HAVE_OWN_ERRNO
-#define CONFIG_HAVE_OWN_ERRNO				1
-#endif
-
-
-/**@brief	Debug printf enable (stdout)*/
-#ifndef CONFIG_DEBUG_PRINTF
-#define CONFIG_DEBUG_PRINTF					1
-#endif
-
-/**@brief	Assert printf enable (stdout)*/
-#ifndef CONFIG_DEBUG_ASSERT
-#define CONFIG_DEBUG_ASSERT					1
-#endif
-
-/**@brief	Statistics of block device*/
-#ifndef CONFIG_BLOCK_DEV_ENABLE_STATS
-#define CONFIG_BLOCK_DEV_ENABLE_STATS		1
-#endif
-
-/**@brief	Cache size of block device.*/
-#ifndef CONFIG_BLOCK_DEV_CACHE_SIZE
-#define CONFIG_BLOCK_DEV_CACHE_SIZE			8
-#endif
-
-
-/**@brief	Ilosc urzadzen blokowych.*/
-#ifndef CONFIG_EXT4_BLOCKDEVS_COUNT
-#define CONFIG_EXT4_BLOCKDEVS_COUNT			2
-#endif
-
-/**@brief	Ilosc punktow montowania systemu plikow*/
-#ifndef CONFIG_EXT4_MOUNTPOINTS_COUNT
-#define CONFIG_EXT4_MOUNTPOINTS_COUNT		2
-#endif
-
-
-#endif /* EXT4_CONFIG_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_debug.c
+++ /dev/null
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_debug.c
- * @brief Debug printf and assert macros.
- */
-
-#include <ext4_config.h>
-#include <ext4_debug.h>
-
-#include <stdarg.h>
-#include <stdio.h>
-
-static uint32_t		__dbg_mask__;
-
-
-void	ext4_dmask_set(uint32_t m)
-{
-    __dbg_mask__ = m;
-}
-
-uint32_t ext4_dmask_get(void)
-{
-    return __dbg_mask__;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_debug.h
+++ /dev/null
@@ -1,116 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_debug.c
- * @brief Debug printf and assert macros.
- */
-
-#ifndef EXT4_DEBUG_H_
-#define EXT4_DEBUG_H_
-
-#include <ext4_config.h>
-#include <ext4_errno.h>
-#include <stdint.h>
-#include <stdio.h>
-
-/**@brief	Debug mask: ext4_blockdev.c*/
-#define EXT4_DEBUG_BLOCKDEV			(1 << 0)
-
-/**@brief	Debug mask: ext4_fs.c*/
-#define EXT4_DEBUG_FS				(1 << 1)
-
-/**@brief	Debug mask: ext4_balloc.c*/
-#define EXT4_DEBUG_BALLOC			(1 << 2)
-
-/**@brief	Debug mask: ext4_bitmap.c*/
-#define EXT4_DEBUG_BITMAP			(1 << 3)
-
-/**@brief	Debug mask: ext4_dir_idx.c*/
-#define EXT4_DEBUG_DIR_IDX			(1 << 4)
-
-/**@brief	Debug mask: ext4_dir.c*/
-#define EXT4_DEBUG_DIR				(1 << 5)
-
-/**@brief	Debug mask: ext4_ialloc.c*/
-#define EXT4_DEBUG_IALLOC			(1 << 6)
-
-/**@brief	Debug mask: ext4_inode.c*/
-#define EXT4_DEBUG_INODE			(1 << 7)
-
-/**@brief	Debug mask: ext4_super.c*/
-#define EXT4_DEBUG_SUPER			(1 << 8)
-
-/**@brief	Debug mask: ext4_bcache.c*/
-#define EXT4_DEBUG_BCACHE			(1 << 9)
-
-
-/**@brief	All debug printf enabled.*/
-#define EXT4_DEBUG_ALL				(0xFFFFFFFF)
-
-/**@brief	Global mask debug settings.
- * @brief	m new debug mask.*/
-void	 ext4_dmask_set(uint32_t m);
-
-/**@brief	Global debug mask get.
- * @return	debug mask*/
-uint32_t ext4_dmask_get(void);
-
-
-#if CONFIG_DEBUG_PRINTF
-/**@brief	Debug printf.*/
-#define 	ext4_dprintf(m, ...)	do {					\
-        (m & ext4_dmask_get()) ? printf(__VA_ARGS__) : (void)0;	\
-        fflush(stdout);											\
-}while(0)
-#else
-#define 	ext4_dprintf(m, ...)
-#endif
-
-
-
-#if CONFIG_DEBUG_ASSERT
-#define 	ext4_assert(_v)	do {						                    \
-        if(!(_v)){											                \
-            printf("Assertion failed:\nModule: %s\nFunc: %s\nLine: %d\n",   \
-                    __FILE__, __FUNCTION__, __LINE__);                      \
-        }                                                                   \
-}while(0)
-#else
-#define 	ext4_assert(_v)
-#endif
-
-
-#endif /* EXT4_DEBUG_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_dir.c
+++ /dev/null
@@ -1,618 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_dir.h
- * @brief Directory handle procedures.
- */
-
-#include <ext4_config.h>
-#include <ext4_dir.h>
-#include <ext4_dir_idx.h>
-#include <ext4_inode.h>
-#include <ext4_fs.h>
-
-#include <string.h>
-
-uint32_t ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de)
-{
-    return to_le32(de->inode);
-}
-
-void 	 ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de,
-        uint32_t inode)
-{
-    de->inode = to_le32(inode);
-}
-
-
-uint16_t ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de)
-{
-    return to_le16(de->entry_length);
-}
-
-void 	 ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de,
-        uint16_t len)
-{
-    de->entry_length = to_le16(len);
-}
-
-
-uint16_t ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb,
-        struct ext4_directory_entry_ll *de)
-{
-    uint16_t v = de->name_length;
-
-    if ((ext4_get32(sb, rev_level) == 0) &&
-            (ext4_get32(sb, minor_rev_level) < 5))
-        v |= ((uint16_t)de->name_length_high) << 8;
-
-    return v;
-}
-void 	ext4_dir_entry_ll_set_name_length(struct ext4_sblock *sb,
-        struct ext4_directory_entry_ll *de, uint16_t len)
-{
-    de->name_length = (len << 8) >> 8;
-
-    if ((ext4_get32(sb, rev_level) == 0) &&
-            (ext4_get32(sb, minor_rev_level) < 5))
-        de->name_length_high = len >> 8;
-}
-
-
-
-uint8_t ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb,
-        struct ext4_directory_entry_ll *de)
-{
-    if ((ext4_get32(sb, rev_level) > 0) ||
-            (ext4_get32(sb, minor_rev_level) >= 5))
-        return de->inode_type;
-
-    return EXT4_DIRECTORY_FILETYPE_UNKNOWN;
-}
-
-
-void 	ext4_dir_entry_ll_set_inode_type(struct ext4_sblock *sb,
-        struct ext4_directory_entry_ll *de, uint8_t type)
-{
-    if ((ext4_get32(sb, rev_level) > 0) ||
-            (ext4_get32(sb, minor_rev_level) >= 5))
-        de->inode_type = type;
-}
-
-/****************************************************************************/
-
-
-static int ext4_dir_iterator_set(struct ext4_directory_iterator *it,
-    uint32_t block_size)
-{
-    it->current = NULL;
-
-    uint32_t offset_in_block = it->current_offset % block_size;
-
-    /* Ensure proper alignment */
-    if ((offset_in_block % 4) != 0)
-        return EIO;
-
-    /* Ensure that the core of the entry does not overflow the block */
-    if (offset_in_block > block_size - 8)
-        return EIO;
-
-    struct ext4_directory_entry_ll *entry =
-            (void *)(it->current_block.data + offset_in_block);
-
-    /* Ensure that the whole entry does not overflow the block */
-    uint16_t length = ext4_dir_entry_ll_get_entry_length(entry);
-    if (offset_in_block + length > block_size)
-        return EIO;
-
-    /* Ensure the name length is not too large */
-    if (ext4_dir_entry_ll_get_name_length(
-            &it->inode_ref->fs->sb, entry) > length-8)
-        return EIO;
-
-    /* Everything OK - "publish" the entry */
-    it->current = entry;
-    return EOK;
-}
-
-static int ext4_dir_iterator_seek(struct ext4_directory_iterator *it,
-    uint64_t pos)
-{
-    uint64_t size = ext4_inode_get_size(&it->inode_ref->fs->sb,
-            it->inode_ref->inode);
-
-    /* The iterator is not valid until we seek to the desired position */
-    it->current = NULL;
-
-    /* Are we at the end? */
-    if (pos >= size) {
-        if (it->current_block.lb_id) {
-
-            int rc = ext4_block_set(it->inode_ref->fs->bdev,
-                    &it->current_block);
-            it->current_block.lb_id = 0;
-
-            if (rc != EOK)
-                return rc;
-        }
-
-        it->current_offset = pos;
-        return EOK;
-    }
-
-    /* Compute next block address */
-    uint32_t block_size =
-            ext4_sb_get_block_size(&it->inode_ref->fs->sb);
-    uint64_t current_block_idx = it->current_offset / block_size;
-    uint64_t next_block_idx = pos / block_size;
-
-    /*
-     * If we don't have a block or are moving accross block boundary,
-     * we need to get another block
-     */
-    if ((it->current_block.lb_id == 0) ||
-            (current_block_idx != next_block_idx)) {
-        if (it->current_block.lb_id) {
-            int rc = ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
-            it->current_block.lb_id = 0;
-
-            if (rc != EOK)
-                return rc;
-        }
-
-        uint32_t next_block_phys_idx;
-        int rc = ext4_fs_get_inode_data_block_index(it->inode_ref,
-                next_block_idx, &next_block_phys_idx);
-        if (rc != EOK)
-            return rc;
-
-
-        rc = ext4_block_get(it->inode_ref->fs->bdev, &it->current_block,
-                next_block_phys_idx);
-        if (rc != EOK) {
-            it->current_block.lb_id = 0;
-            return rc;
-        }
-    }
-
-    it->current_offset = pos;
-
-    return ext4_dir_iterator_set(it, block_size);
-}
-
-
-int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
-        struct ext4_inode_ref *inode_ref, uint64_t pos)
-{
-    it->inode_ref = inode_ref;
-    it->current = 0;
-    it->current_offset = 0;
-    it->current_block.lb_id = 0;
-
-    return ext4_dir_iterator_seek(it, pos);
-}
-
-int ext4_dir_iterator_next(struct ext4_directory_iterator *it)
-{
-    uint16_t skip = ext4_dir_entry_ll_get_entry_length(it->current);
-
-    return ext4_dir_iterator_seek(it, it->current_offset + skip);
-}
-
-int ext4_dir_iterator_fini(struct ext4_directory_iterator *it)
-{
-    it->current = 0;
-
-    if (it->current_block.lb_id)
-        return ext4_block_set(it->inode_ref->fs->bdev, &it->current_block);
-
-    return EOK;
-}
-
-void ext4_dir_write_entry(struct ext4_sblock *sb,
-    struct ext4_directory_entry_ll *entry, uint16_t entry_len,
-    struct ext4_inode_ref *child,  const char *name, size_t name_len)
-{
-    /* Check maximum entry length */
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-    ext4_assert(entry_len <= block_size);
-
-    /* Set basic attributes */
-    ext4_dir_entry_ll_set_inode(entry, child->index);
-    ext4_dir_entry_ll_set_entry_length(entry, entry_len);
-    ext4_dir_entry_ll_set_name_length(sb, entry, name_len);
-
-    /* Write name */
-    memcpy(entry->name, name, name_len);
-
-    /* Set type of entry */
-    if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY))
-        ext4_dir_entry_ll_set_inode_type(sb, entry,
-                EXT4_DIRECTORY_FILETYPE_DIR);
-    else
-        ext4_dir_entry_ll_set_inode_type(sb, entry,
-                EXT4_DIRECTORY_FILETYPE_REG_FILE);
-}
-
-int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
-        uint32_t name_len, struct ext4_inode_ref *child)
-{
-    struct ext4_fs *fs = parent->fs;
-
-#if CONFIG_DIR_INDEX_ENABLE
-    /* Index adding (if allowed) */
-    if ((ext4_sb_check_feature_compatible(&fs->sb,
-            EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
-            (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
-        int rc = ext4_dir_dx_add_entry(parent, child, name);
-
-        /* Check if index is not corrupted */
-        if (rc != EXT4_ERR_BAD_DX_DIR) {
-            if (rc != EOK)
-                return rc;
-
-            return EOK;
-        }
-
-        /* Needed to clear dir index flag if corrupted */
-        ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
-        parent->dirty = true;
-    }
-#endif
-
-    /* Linear algorithm */
-    uint32_t iblock = 0;
-    uint32_t fblock = 0;
-    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
-    uint32_t inode_size = ext4_inode_get_size(&fs->sb, parent->inode);
-    uint32_t total_blocks = inode_size / block_size;
-
-
-    /* Find block, where is space for new entry and try to add */
-    bool success = false;
-    for (iblock = 0; iblock < total_blocks; ++iblock) {
-        int rc = ext4_fs_get_inode_data_block_index(parent,
-                iblock, &fblock);
-        if (rc != EOK)
-            return rc;
-
-
-        struct ext4_block block;
-        rc = ext4_block_get(fs->bdev, &block, fblock);
-        if (rc != EOK)
-            return rc;
-
-        /* If adding is successful, function can finish */
-        rc = ext4_dir_try_insert_entry(&fs->sb, &block,
-                child, name, name_len);
-        if (rc == EOK)
-            success = true;
-
-        rc = ext4_block_set(fs->bdev, &block);
-        if (rc != EOK)
-            return rc;
-
-        if (success)
-            return EOK;
-    }
-
-    /* No free block found - needed to allocate next data block */
-
-    iblock = 0;
-    fblock = 0;
-    int rc = ext4_fs_append_inode_block(parent, &fblock, &iblock);
-    if (rc != EOK)
-        return rc;
-
-    /* Load new block */
-    struct ext4_block new_block;
-
-    rc = ext4_block_get(fs->bdev, &new_block, fblock);
-    if (rc != EOK)
-        return rc;
-
-    /* Fill block with zeroes */
-    memset(new_block.data, 0, block_size);
-    struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
-    ext4_dir_write_entry(&fs->sb, block_entry, block_size,
-            child, name, name_len);
-
-    /* Save new block */
-    new_block.dirty = true;
-    rc = ext4_block_set(fs->bdev, &new_block);
-
-    return rc;
-}
-
-int ext4_dir_find_entry(struct ext4_directory_search_result *result,
-        struct ext4_inode_ref *parent, const char *name, uint32_t name_len)
-{
-    struct ext4_sblock *sb = &parent->fs->sb;
-
-
-#if CONFIG_DIR_INDEX_ENABLE
-    /* Index search */
-    if ((ext4_sb_check_feature_compatible(sb,
-            EXT4_FEATURE_COMPAT_DIR_INDEX)) &&
-            (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
-        int rc = ext4_dir_dx_find_entry(result, parent, name_len,
-                name);
-
-        /* Check if index is not corrupted */
-        if (rc != EXT4_ERR_BAD_DX_DIR) {
-            if (rc != EOK)
-                return rc;
-
-            return EOK;
-        }
-
-        /* Needed to clear dir index flag if corrupted */
-        ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
-        parent->dirty = true;
-    }
-#endif
-
-    /* Linear algorithm */
-
-    uint32_t iblock;
-    uint32_t fblock;
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-    uint32_t inode_size = ext4_inode_get_size(sb, parent->inode);
-    uint32_t total_blocks = inode_size / block_size;
-
-    /* Walk through all data blocks */
-    for (iblock = 0; iblock < total_blocks; ++iblock) {
-        /* Load block address */
-        int rc = ext4_fs_get_inode_data_block_index(parent, iblock,
-                &fblock);
-        if (rc != EOK)
-            return rc;
-
-        /* Load data block */
-        struct ext4_block block;
-        rc = ext4_block_get( parent->fs->bdev, &block, fblock);
-        if (rc != EOK)
-            return rc;
-
-        /* Try to find entry in block */
-        struct ext4_directory_entry_ll *res_entry;
-        rc = ext4_dir_find_in_block(&block, sb, name_len, name,
-                &res_entry);
-        if (rc == EOK) {
-            result->block = block;
-            result->dentry = res_entry;
-            return EOK;
-        }
-
-        /* Entry not found - put block and continue to the next block */
-
-        rc = ext4_block_set(parent->fs->bdev, &block);
-        if (rc != EOK)
-            return rc;
-    }
-
-    /* Entry was not found */
-
-    result->block.lb_id =  0;
-    result->dentry 		=  NULL;
-
-    return ENOENT;
-}
-
-int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
-    uint32_t name_len)
-{
-    /* Check if removing from directory */
-    if (!ext4_inode_is_type(&parent->fs->sb, parent->inode,
-            EXT4_INODE_MODE_DIRECTORY))
-        return ENOTDIR;
-
-    /* Try to find entry */
-    struct ext4_directory_search_result result;
-    int rc = ext4_dir_find_entry(&result, parent, name, name_len);
-    if (rc != EOK)
-        return rc;
-
-    /* Invalidate entry */
-    ext4_dir_entry_ll_set_inode(result.dentry, 0);
-
-    /* Store entry position in block */
-    uint32_t pos = (uint8_t *) result.dentry - result.block.data;
-
-    /*
-     * If entry is not the first in block, it must be merged
-     * with previous entry
-     */
-    if (pos != 0) {
-        uint32_t offset = 0;
-
-        /* Start from the first entry in block */
-        struct ext4_directory_entry_ll *tmp_dentry = (void *)result.block.data;
-        uint16_t tmp_dentry_length =
-                ext4_dir_entry_ll_get_entry_length(tmp_dentry);
-
-        /* Find direct predecessor of removed entry */
-        while ((offset + tmp_dentry_length) < pos) {
-            offset +=
-                    ext4_dir_entry_ll_get_entry_length(tmp_dentry);
-            tmp_dentry = (void *)(result.block.data + offset);
-            tmp_dentry_length =
-                    ext4_dir_entry_ll_get_entry_length(tmp_dentry);
-        }
-
-        ext4_assert(tmp_dentry_length + offset == pos);
-
-        /* Add to removed entry length to predecessor's length */
-        uint16_t del_entry_length =
-                ext4_dir_entry_ll_get_entry_length(result.dentry);
-        ext4_dir_entry_ll_set_entry_length(tmp_dentry,
-                tmp_dentry_length + del_entry_length);
-    }
-
-    result.block.dirty = true;
-
-    return ext4_dir_destroy_result(parent, &result);
-}
-
-int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
-    struct ext4_block *target_block, struct ext4_inode_ref *child,
-    const char *name, uint32_t name_len)
-{
-    /* Compute required length entry and align it to 4 bytes */
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-    uint16_t required_len = sizeof(struct ext4_fake_directory_entry) + name_len;
-
-    if ((required_len % 4) != 0)
-        required_len += 4 - (required_len % 4);
-
-    /* Initialize pointers, stop means to upper bound */
-    struct ext4_directory_entry_ll *dentry  = (void *)target_block->data;
-    struct ext4_directory_entry_ll *stop 	=
-            (void *)(target_block->data + block_size);
-
-    /*
-     * Walk through the block and check for invalid entries
-     * or entries with free space for new entry
-     */
-    while (dentry < stop) {
-        uint32_t inode = ext4_dir_entry_ll_get_inode(dentry);
-        uint16_t rec_len = ext4_dir_entry_ll_get_entry_length(dentry);
-
-        /* If invalid and large enough entry, use it */
-        if ((inode == 0) && (rec_len >= required_len)) {
-            ext4_dir_write_entry(sb, dentry, rec_len, child,
-                    name, name_len);
-            target_block->dirty = true;
-
-            return EOK;
-        }
-
-        /* Valid entry, try to split it */
-        if (inode != 0) {
-            uint16_t used_name_len =
-                    ext4_dir_entry_ll_get_name_length(sb, dentry);
-
-            uint16_t used_space =
-                    sizeof(struct ext4_fake_directory_entry) + used_name_len;
-
-            if ((used_name_len % 4) != 0)
-                used_space += 4 - (used_name_len % 4);
-
-            uint16_t free_space = rec_len - used_space;
-
-            /* There is free space for new entry */
-            if (free_space >= required_len) {
-                /* Cut tail of current entry */
-                ext4_dir_entry_ll_set_entry_length(dentry, used_space);
-                struct ext4_directory_entry_ll *new_entry =
-                        (void *) dentry + used_space;
-                ext4_dir_write_entry(sb, new_entry,
-                        free_space, child, name, name_len);
-
-                target_block->dirty = true;
-
-                return EOK;
-            }
-        }
-
-        /* Jump to the next entry */
-        dentry = (void *) dentry + rec_len;
-    }
-
-    /* No free space found for new entry */
-    return ENOSPC;
-}
-
-
-int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
-        size_t name_len, const char *name,
-        struct ext4_directory_entry_ll **res_entry)
-{
-    /* Start from the first entry in block */
-    struct ext4_directory_entry_ll *dentry =
-            (struct ext4_directory_entry_ll *) block->data;
-
-    /* Set upper bound for cycling */
-    uint8_t *addr_limit = block->data + ext4_sb_get_block_size(sb);
-
-    /* Walk through the block and check entries */
-    while ((uint8_t *) dentry < addr_limit) {
-        /* Termination condition */
-        if ((uint8_t *) dentry + name_len > addr_limit)
-            break;
-
-        /* Valid entry - check it */
-        if (dentry->inode != 0) {
-            /* For more effectivity compare firstly only lengths */
-            if (ext4_dir_entry_ll_get_name_length(sb, dentry) ==
-                    name_len) {
-                /* Compare names */
-                if (memcmp((uint8_t *) name, dentry->name, name_len) == 0) {
-                    *res_entry = dentry;
-                    return EOK;
-                }
-            }
-        }
-
-        uint16_t dentry_len =
-                ext4_dir_entry_ll_get_entry_length(dentry);
-
-        /* Corrupted entry */
-        if (dentry_len == 0)
-            return EINVAL;
-
-        /* Jump to next entry */
-        dentry = (struct ext4_directory_entry_ll *)
-                ((uint8_t *) dentry + dentry_len);
-    }
-
-    /* Entry not found */
-    return ENOENT;
-}
-
-int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
-    struct ext4_directory_search_result *result)
-{
-    if (result->block.lb_id)
-        return ext4_block_set(parent->fs->bdev, &result->block);
-
-    return EOK;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_dir.h
+++ /dev/null
@@ -1,114 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_dir.h
- * @brief Directory handle procedures.
- */
-
-#ifndef EXT4_DIR_H_
-#define EXT4_DIR_H_
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-#include <ext4_blockdev.h>
-#include <ext4_super.h>
-
-
-#include <stdint.h>
-
-uint32_t ext4_dir_entry_ll_get_inode(struct ext4_directory_entry_ll *de);
-
-void ext4_dir_entry_ll_set_inode(struct ext4_directory_entry_ll *de,
-    uint32_t inode);
-
-
-uint16_t ext4_dir_entry_ll_get_entry_length(struct ext4_directory_entry_ll *de);
-void ext4_dir_entry_ll_set_entry_length(struct ext4_directory_entry_ll *de,
-    uint16_t len);
-
-
-uint16_t ext4_dir_entry_ll_get_name_length(struct ext4_sblock *sb,
-    struct ext4_directory_entry_ll *de);
-void ext4_dir_entry_ll_set_name_length(struct ext4_sblock *sb,
-    struct ext4_directory_entry_ll *de, uint16_t len);
-
-
-
-uint8_t ext4_dir_entry_ll_get_inode_type(struct ext4_sblock *sb,
-    struct ext4_directory_entry_ll *de);
-void 	ext4_dir_entry_ll_set_inode_type(struct ext4_sblock *sb,
-    struct ext4_directory_entry_ll *de, uint8_t type);
-
-
-int ext4_dir_iterator_init(struct ext4_directory_iterator *it,
-    struct ext4_inode_ref *inode_ref, uint64_t pos);
-
-int ext4_dir_iterator_next(struct ext4_directory_iterator *it);
-int ext4_dir_iterator_fini(struct ext4_directory_iterator *it);
-
-void ext4_dir_write_entry(struct ext4_sblock *sb,
-    struct ext4_directory_entry_ll *entry, uint16_t entry_len,
-    struct ext4_inode_ref *child,  const char *name, size_t name_len);
-
-int ext4_dir_add_entry(struct ext4_inode_ref *parent, const char *name,
-        uint32_t name_len, struct ext4_inode_ref *child);
-
-int ext4_dir_find_entry(struct ext4_directory_search_result *result,
-        struct ext4_inode_ref *parent, const char *name, uint32_t name_len);
-
-int ext4_dir_remove_entry(struct ext4_inode_ref *parent, const char *name,
-    uint32_t name_len);
-
-int ext4_dir_try_insert_entry(struct ext4_sblock *sb,
-    struct ext4_block *target_block, struct ext4_inode_ref *child,
-    const char *name, uint32_t name_len);
-
-int ext4_dir_find_in_block(struct ext4_block *block, struct ext4_sblock *sb,
-    size_t name_len, const char *name,
-    struct ext4_directory_entry_ll **res_entry);
-
-int ext4_dir_destroy_result(struct ext4_inode_ref *parent,
-    struct ext4_directory_search_result *result);
-
-
-#endif /* EXT4_DIR_H_ */
-
-/**
- * @}
- */
-
-
--- a/src/lwext4/ext4_dir_idx.c
+++ /dev/null
@@ -1,1016 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_dir_idx.c
- * @brief Directory indexing procedures.
- */
-
-#include <ext4_config.h>
-#include <ext4_dir_idx.h>
-#include <ext4_dir.h>
-#include <ext4_blockdev.h>
-#include <ext4_fs.h>
-#include <ext4_super.h>
-#include <ext4_hash.h>
-
-#include <string.h>
-#include <stdlib.h>
-
-struct ext4_dx_sort_entry {
-    uint32_t hash;
-    uint32_t rec_len;
-    void 	 *dentry;
-};
-
-static int ext4_dir_dx_hash_string(struct ext4_hash_info *hinfo, int len,
-    const char *name)
-{
-    return ext2_htree_hash(name, len, hinfo->seed, hinfo->hash_version,
-            &hinfo->hash, &hinfo->minor_hash);
-}
-
-
-uint8_t ext4_dir_dx_root_info_get_hash_version(
-        struct ext4_directory_dx_root_info *root_info)
-{
-    return root_info->hash_version;
-}
-
-
-void 	ext4_dir_dx_root_info_set_hash_version(
-        struct ext4_directory_dx_root_info  *root_info, uint8_t v)
-{
-    root_info->hash_version = v;
-}
-
-uint8_t ext4_dir_dx_root_info_get_info_length(
-        struct ext4_directory_dx_root_info *root_info)
-{
-    return root_info->info_length;
-}
-void 	ext4_dir_dx_root_info_set_info_length(
-        struct ext4_directory_dx_root_info  *root_info, uint8_t len)
-{
-    root_info->info_length = len;
-}
-
-uint8_t ext4_dir_dx_root_info_get_indirect_levels(
-        struct ext4_directory_dx_root_info *root_info)
-{
-    return root_info->indirect_levels;
-}
-
-void 	ext4_dir_dx_root_info_set_indirect_levels(
-        struct ext4_directory_dx_root_info *root_info, uint8_t lvl)
-{
-    root_info->indirect_levels = lvl;
-}
-
-
-
-uint16_t ext4_dir_dx_countlimit_get_limit(
-        struct ext4_directory_dx_countlimit *climit)
-{
-    return to_le16(climit->limit);
-}
-void 	ext4_dir_dx_countlimit_set_limit(
-        struct ext4_directory_dx_countlimit *climit, uint16_t limit)
-{
-    climit->limit = to_le16(limit);
-}
-
-uint16_t ext4_dir_dx_countlimit_get_count(
-        struct ext4_directory_dx_countlimit *climit)
-{
-    return to_le16(climit->count);
-}
-
-void 	ext4_dir_dx_countlimit_set_count(
-        struct ext4_directory_dx_countlimit *climit, uint16_t count)
-{
-    climit->count = to_le16(count);
-}
-
-
-uint32_t ext4_dir_dx_entry_get_hash(
-        struct ext4_directory_dx_entry *entry)
-{
-    return to_le32(entry->hash);
-}
-void ext4_dir_dx_entry_set_hash(
-        struct ext4_directory_dx_entry *entry, uint32_t hash)
-{
-    entry->hash = to_le32(hash);
-}
-
-uint32_t ext4_dir_dx_entry_get_block(
-        struct ext4_directory_dx_entry *entry)
-{
-    return to_le32(entry->block);
-}
-void 	ext4_dir_dx_entry_set_block(
-        struct ext4_directory_dx_entry *entry, uint32_t block)
-{
-    entry->block = to_le32(block);
-}
-/****************************************************************************/
-
-int 	ext4_dir_dx_init(struct ext4_inode_ref *dir)
-{
-    /* Load block 0, where will be index root located */
-    uint32_t fblock;
-    int rc = ext4_fs_get_inode_data_block_index(dir, 0,
-            &fblock);
-    if (rc != EOK)
-        return rc;
-
-    struct ext4_block block;
-    rc = ext4_block_get(dir->fs->bdev, &block, fblock);
-    if (rc != EOK)
-        return rc;
-
-    /* Initialize pointers to data structures */
-    struct ext4_directory_dx_root *root = (void *)block.data;
-    struct ext4_directory_dx_root_info *info = &(root->info);
-
-    /* Initialize root info structure */
-    uint8_t hash_version = ext4_get8(&dir->fs->sb, default_hash_version);
-
-
-    ext4_dir_dx_root_info_set_hash_version(info, hash_version);
-    ext4_dir_dx_root_info_set_indirect_levels(info, 0);
-    ext4_dir_dx_root_info_set_info_length(info, 8);
-
-    /* Set limit and current number of entries */
-    struct ext4_directory_dx_countlimit *countlimit =
-            (struct ext4_directory_dx_countlimit *) &root->entries;
-
-    ext4_dir_dx_countlimit_set_count(countlimit, 1);
-
-    uint32_t block_size =
-            ext4_sb_get_block_size(&dir->fs->sb);
-    uint32_t entry_space =
-            block_size - 2 * sizeof(struct ext4_directory_dx_dot_entry) -
-            sizeof(struct ext4_directory_dx_root_info);
-    uint16_t root_limit = entry_space / sizeof(struct ext4_directory_dx_entry);
-    ext4_dir_dx_countlimit_set_limit(countlimit, root_limit);
-
-    /* Append new block, where will be new entries inserted in the future */
-    uint32_t iblock;
-    rc = ext4_fs_append_inode_block(dir, &fblock, &iblock);
-    if (rc != EOK) {
-        ext4_block_set(dir->fs->bdev, &block);
-        return rc;
-    }
-
-    struct ext4_block new_block;
-
-    rc = ext4_block_get(dir->fs->bdev, &new_block, fblock);
-    if (rc != EOK) {
-        ext4_block_set(dir->fs->bdev, &block);
-        return rc;
-    }
-
-    /* Fill the whole block with empty entry */
-    struct ext4_directory_entry_ll *block_entry = (void *)new_block.data;
-
-    ext4_dir_entry_ll_set_entry_length(block_entry, block_size);
-    ext4_dir_entry_ll_set_inode(block_entry, 0);
-
-    new_block.dirty = true;
-    rc = ext4_block_set(dir->fs->bdev, &new_block);
-    if (rc != EOK) {
-        ext4_block_set(dir->fs->bdev, &block);
-        return rc;
-    }
-
-    /* Connect new block to the only entry in index */
-    struct ext4_directory_dx_entry *entry = root->entries;
-    ext4_dir_dx_entry_set_block(entry, iblock);
-
-    block.dirty = true;
-
-    return ext4_block_set(dir->fs->bdev, &block);
-}
-
-static int ext4_dir_hinfo_init(struct ext4_hash_info *hinfo,
-        struct ext4_block *root_block, struct ext4_sblock *sb, size_t name_len,
-        const char *name)
-{
-    struct ext4_directory_dx_root *root =
-            (struct ext4_directory_dx_root *) root_block->data;
-
-    if ((root->info.hash_version != EXT2_HTREE_LEGACY) &&
-            (root->info.hash_version != EXT2_HTREE_HALF_MD4) &&
-            (root->info.hash_version != EXT2_HTREE_TEA))
-        return EXT4_ERR_BAD_DX_DIR;
-
-    /* Check unused flags */
-    if (root->info.unused_flags != 0)
-        return EXT4_ERR_BAD_DX_DIR;
-
-    /* Check indirect levels */
-    if (root->info.indirect_levels > 1)
-        return EXT4_ERR_BAD_DX_DIR;
-
-    /* Check if node limit is correct */
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-    uint32_t entry_space = block_size;
-    entry_space -= 2 * sizeof(struct ext4_directory_dx_dot_entry);
-    entry_space -= sizeof(struct ext4_directory_dx_root_info);
-    entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
-
-    uint16_t limit = ext4_dir_dx_countlimit_get_limit(
-            (struct ext4_directory_dx_countlimit *) &root->entries);
-    if (limit != entry_space)
-        return EXT4_ERR_BAD_DX_DIR;
-
-    /* Check hash version and modify if necessary */
-    hinfo->hash_version =
-            ext4_dir_dx_root_info_get_hash_version(&root->info);
-    if ((hinfo->hash_version <= EXT2_HTREE_TEA) &&
-            (ext4_sb_check_flag(sb, EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH))) {
-        /* Use unsigned hash */
-        hinfo->hash_version += 3;
-    }
-
-    /* Load hash seed from superblock */
-
-    hinfo->seed = ext4_get8(sb, hash_seed);
-
-    /* Compute hash value of name */
-    if (name)
-        return ext4_dir_dx_hash_string(hinfo, name_len, name);
-
-    return EOK;
-}
-
-
-static int ext4_dir_dx_get_leaf(struct ext4_hash_info *hinfo,
-        struct ext4_inode_ref *inode_ref, struct ext4_block *root_block,
-        struct ext4_directory_dx_block **dx_block,
-        struct ext4_directory_dx_block *dx_blocks)
-{
-    struct ext4_directory_dx_block *tmp_dx_block = dx_blocks;
-    struct ext4_directory_dx_root *root =
-            (struct ext4_directory_dx_root *) root_block->data;
-    struct ext4_directory_dx_entry *entries =
-            (struct ext4_directory_dx_entry *) &root->entries;
-
-    uint16_t limit = ext4_dir_dx_countlimit_get_limit(
-            (struct ext4_directory_dx_countlimit *) entries);
-    uint8_t indirect_level =
-            ext4_dir_dx_root_info_get_indirect_levels(&root->info);
-
-    struct ext4_block *tmp_block = root_block;
-    struct ext4_directory_dx_entry *p;
-    struct ext4_directory_dx_entry *q;
-    struct ext4_directory_dx_entry *m;
-    struct ext4_directory_dx_entry *at;
-
-    /* Walk through the index tree */
-    while (true) {
-        uint16_t count = ext4_dir_dx_countlimit_get_count(
-                (struct ext4_directory_dx_countlimit *) entries);
-        if ((count == 0) || (count > limit))
-            return EXT4_ERR_BAD_DX_DIR;
-
-        /* Do binary search in every node */
-        p = entries + 1;
-        q = entries + count - 1;
-
-        while (p <= q) {
-            m = p + (q - p) / 2;
-            if (ext4_dir_dx_entry_get_hash(m) > hinfo->hash)
-                q = m - 1;
-            else
-                p = m + 1;
-        }
-
-        at = p - 1;
-
-        /* Write results */
-
-        memcpy(&tmp_dx_block->block, tmp_block, sizeof(struct ext4_block));
-        tmp_dx_block->entries = entries;
-        tmp_dx_block->position = at;
-
-        /* Is algorithm in the leaf? */
-        if (indirect_level == 0) {
-            *dx_block = tmp_dx_block;
-            return EOK;
-        }
-
-        /* Goto child node */
-        uint32_t next_block = ext4_dir_dx_entry_get_block(at);
-
-        indirect_level--;
-
-        uint32_t fblock;
-        int rc = ext4_fs_get_inode_data_block_index(inode_ref,
-                next_block, &fblock);
-        if (rc != EOK)
-            return rc;
-
-        rc = ext4_block_get(inode_ref->fs->bdev, tmp_block, fblock);
-        if (rc != EOK)
-            return rc;
-
-        entries = ((struct ext4_directory_dx_node *) tmp_block->data)->entries;
-        limit = ext4_dir_dx_countlimit_get_limit(
-                (struct ext4_directory_dx_countlimit *) entries);
-
-        uint16_t entry_space =
-                ext4_sb_get_block_size(&inode_ref->fs->sb) -
-                sizeof(struct ext4_directory_dx_dot_entry);
-
-        entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);
-
-        if (limit != entry_space) {
-            ext4_block_set(inode_ref->fs->bdev, tmp_block);
-            return EXT4_ERR_BAD_DX_DIR;
-        }
-
-        ++tmp_dx_block;
-    }
-
-    /* Unreachable */
-    return EOK;
-}
-
-static int ext4_dir_dx_next_block(struct ext4_inode_ref *inode_ref,
-        uint32_t hash, struct ext4_directory_dx_block *dx_block,
-        struct ext4_directory_dx_block *dx_blocks)
-{
-    uint32_t num_handles = 0;
-    struct ext4_directory_dx_block *p = dx_block;
-
-    /* Try to find data block with next bunch of entries */
-    while (true) {
-        p->position++;
-        uint16_t count = ext4_dir_dx_countlimit_get_count(
-                (struct ext4_directory_dx_countlimit *) p->entries);
-
-        if (p->position < p->entries + count)
-            break;
-
-        if (p == dx_blocks)
-            return EOK;
-
-        num_handles++;
-        p--;
-    }
-
-    /* Check hash collision (if not occured - no next block cannot be used)*/
-    uint32_t current_hash = ext4_dir_dx_entry_get_hash(p->position);
-    if ((hash & 1) == 0) {
-        if ((current_hash & ~1) != hash)
-            return 0;
-    }
-
-    /* Fill new path */
-    while (num_handles--) {
-        uint32_t block_idx =
-                ext4_dir_dx_entry_get_block(p->position);
-        uint32_t block_addr;
-
-        int rc = ext4_fs_get_inode_data_block_index(inode_ref,
-                block_idx, &block_addr);
-        if (rc != EOK)
-            return rc;
-
-
-        struct ext4_block block;
-        rc = ext4_block_get(inode_ref->fs->bdev, &block, block_addr);
-        if (rc != EOK)
-            return rc;
-
-        p++;
-
-        /* Don't forget to put old block (prevent memory leak) */
-        ext4_block_set(inode_ref->fs->bdev, &p->block);
-
-
-
-        memcpy(&p->block, &p->block, sizeof(block));
-        p->entries = ((struct ext4_directory_dx_node *) block.data)->entries;
-        p->position = p->entries;
-    }
-
-    return ENOENT;
-}
-
-
-
-int 	ext4_dir_dx_find_entry(struct ext4_directory_search_result * result,
-        struct ext4_inode_ref *inode_ref, size_t name_len, const char *name)
-{
-    /* Load direct block 0 (index root) */
-    uint32_t root_block_addr;
-    int rc = ext4_fs_get_inode_data_block_index(inode_ref, 0,
-            &root_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    struct ext4_fs *fs = inode_ref->fs;
-
-    struct ext4_block root_block;
-    rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Initialize hash info (compute hash value) */
-    struct ext4_hash_info hinfo;
-    rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb,
-            name_len, name);
-    if (rc != EOK) {
-        ext4_block_set(fs->bdev, &root_block);
-        return EXT4_ERR_BAD_DX_DIR;
-    }
-
-    /*
-     * Hardcoded number 2 means maximum height of index tree,
-     * specified in the Linux driver.
-     */
-    struct ext4_directory_dx_block dx_blocks[2];
-    struct ext4_directory_dx_block *dx_block;
-    struct ext4_directory_dx_block *tmp;
-
-    rc = ext4_dir_dx_get_leaf(&hinfo, inode_ref, &root_block,
-            &dx_block, dx_blocks);
-    if (rc != EOK) {
-        ext4_block_set(fs->bdev, &root_block);
-        return EXT4_ERR_BAD_DX_DIR;
-    }
-
-    do {
-        /* Load leaf block */
-        uint32_t leaf_block_idx =
-                ext4_dir_dx_entry_get_block(dx_block->position);
-        uint32_t leaf_block_addr;
-
-        rc = ext4_fs_get_inode_data_block_index(inode_ref,
-                leaf_block_idx, &leaf_block_addr);
-        if (rc != EOK)
-            goto cleanup;
-
-        struct ext4_block leaf_block;
-        rc = ext4_block_get(fs->bdev, &leaf_block, leaf_block_addr);
-        if (rc != EOK)
-            goto cleanup;
-
-        /* Linear search inside block */
-        struct ext4_directory_entry_ll *res_dentry;
-        rc = ext4_dir_find_in_block(&leaf_block, &fs->sb,
-                name_len, name, &res_dentry);
-
-        /* Found => return it */
-        if (rc == EOK) {
-            result->block = leaf_block;
-            result->dentry = res_dentry;
-            goto cleanup;
-        }
-
-        /* Not found, leave untouched */
-        ext4_block_set(fs->bdev, &leaf_block);
-
-        if (rc != ENOENT)
-            goto cleanup;
-
-        /* check if the next block could be checked */
-        rc = ext4_dir_dx_next_block(inode_ref, hinfo.hash,
-                dx_block, &dx_blocks[0]);
-        if (rc < 0)
-            goto cleanup;
-    } while (rc == ENOENT);
-
-    /* Entry not found */
-    rc = ENOENT;
-
-    cleanup:
-    /* The whole path must be released (preventing memory leak) */
-    tmp = dx_blocks;
-
-    while (tmp <= dx_block) {
-        ext4_block_set(fs->bdev, &tmp->block);
-        ++tmp;
-    }
-
-    return rc;
-}
-
-static int ext4_dir_dx_entry_comparator(const void *arg1, const void *arg2)
-{
-    struct ext4_dx_sort_entry *entry1 = (void *)arg1;
-    struct ext4_dx_sort_entry *entry2 = (void *)arg2;
-
-    if (entry1->hash == entry2->hash)
-        return 0;
-
-    if (entry1->hash < entry2->hash)
-        return -1;
-    else
-        return 1;
-}
-
-static void ext4_dir_dx_insert_entry(
-        struct ext4_directory_dx_block *index_block, uint32_t hash,
-        uint32_t iblock)
-{
-    struct ext4_directory_dx_entry *old_index_entry = index_block->position;
-    struct ext4_directory_dx_entry *new_index_entry = old_index_entry + 1;
-
-    struct ext4_directory_dx_countlimit *countlimit =
-            (struct ext4_directory_dx_countlimit *) index_block->entries;
-    uint32_t count = ext4_dir_dx_countlimit_get_count(countlimit);
-
-    struct ext4_directory_dx_entry *start_index = index_block->entries;
-    size_t bytes = (void *) (start_index + count) - (void *) (new_index_entry);
-
-    memmove(new_index_entry + 1, new_index_entry, bytes);
-
-    ext4_dir_dx_entry_set_block(new_index_entry, iblock);
-    ext4_dir_dx_entry_set_hash(new_index_entry, hash);
-
-    ext4_dir_dx_countlimit_set_count(countlimit, count + 1);
-
-    index_block->block.dirty = true;
-}
-
-static int ext4_dir_dx_split_data(struct ext4_inode_ref *inode_ref,
-        struct ext4_hash_info *hinfo, struct ext4_block *old_data_block,
-        struct ext4_directory_dx_block *index_block,
-        struct ext4_block *new_data_block)
-{
-    int rc = EOK;
-
-    /* Allocate buffer for directory entries */
-    uint32_t block_size =
-            ext4_sb_get_block_size(&inode_ref->fs->sb);
-
-    void *entry_buffer = malloc(block_size);
-    if (entry_buffer == NULL)
-        return ENOMEM;
-
-    /* dot entry has the smallest size available */
-    uint32_t max_entry_count =
-            block_size / sizeof(struct ext4_directory_dx_dot_entry);
-
-    /* Allocate sort entry */
-    struct ext4_dx_sort_entry *sort_array =
-            malloc(max_entry_count * sizeof(struct ext4_dx_sort_entry));
-
-    if (sort_array == NULL) {
-        free(entry_buffer);
-        return ENOMEM;
-    }
-
-    uint32_t idx = 0;
-    uint32_t real_size = 0;
-
-    /* Initialize hinfo */
-    struct ext4_hash_info tmp_hinfo;
-    memcpy(&tmp_hinfo, hinfo, sizeof(struct ext4_hash_info));
-
-    /* Load all valid entries to the buffer */
-    struct ext4_directory_entry_ll *dentry = (void *)old_data_block->data;
-    void *entry_buffer_ptr = entry_buffer;
-    while ((void *)dentry < (void *)(old_data_block->data + block_size)) {
-        /* Read only valid entries */
-        if (ext4_dir_entry_ll_get_inode(dentry) != 0) {
-            uint8_t len = ext4_dir_entry_ll_get_name_length(
-                    &inode_ref->fs->sb, dentry);
-
-            rc = ext4_dir_dx_hash_string(&tmp_hinfo, len, (char*)dentry->name);
-            if(rc != EOK) {
-                free(sort_array);
-                free(entry_buffer);
-                return rc;
-            }
-
-            uint32_t rec_len = 8 + len;
-
-            if ((rec_len % 4) != 0)
-                rec_len += 4 - (rec_len % 4);
-
-            memcpy(entry_buffer_ptr, dentry, rec_len);
-
-            sort_array[idx].dentry = entry_buffer_ptr;
-            sort_array[idx].rec_len = rec_len;
-            sort_array[idx].hash = tmp_hinfo.hash;
-
-            entry_buffer_ptr += rec_len;
-            real_size += rec_len;
-            idx++;
-        }
-
-        dentry = (void *) dentry +
-                ext4_dir_entry_ll_get_entry_length(dentry);
-    }
-
-    /* Sort all entries */
-    qsort(sort_array, idx, sizeof(struct ext4_dx_sort_entry),
-            ext4_dir_dx_entry_comparator);
-
-    /* Allocate new block for store the second part of entries */
-    uint32_t new_fblock;
-    uint32_t new_iblock;
-    rc = ext4_fs_append_inode_block(inode_ref, &new_fblock,
-            &new_iblock);
-    if (rc != EOK) {
-        free(sort_array);
-        free(entry_buffer);
-        return rc;
-    }
-
-    /* Load new block */
-    struct ext4_block new_data_block_tmp;
-    rc = ext4_block_get(inode_ref->fs->bdev, &new_data_block_tmp,
-            new_fblock);
-    if (rc != EOK) {
-        free(sort_array);
-        free(entry_buffer);
-        return rc;
-    }
-
-    /*
-     * Distribute entries to two blocks (by size)
-     * - compute the half
-     */
-    uint32_t new_hash = 0;
-    uint32_t current_size = 0;
-    uint32_t mid = 0;
-    uint32_t i;
-    for ( i = 0; i < idx; ++i) {
-        if ((current_size + sort_array[i].rec_len) > (real_size / 2)) {
-            new_hash = sort_array[i].hash;
-            mid = i;
-            break;
-        }
-
-        current_size += sort_array[i].rec_len;
-    }
-
-    /* Check hash collision */
-    uint32_t continued = 0;
-    if (new_hash == sort_array[mid-1].hash)
-        continued = 1;
-
-    uint32_t offset = 0;
-    void *ptr;
-
-    /* First part - to the old block */
-    for (i = 0; i < mid; ++i) {
-        ptr = old_data_block->data + offset;
-        memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
-
-        struct ext4_directory_entry_ll *tmp = ptr;
-        if (i < (mid - 1))
-            ext4_dir_entry_ll_set_entry_length(tmp,
-                    sort_array[i].rec_len);
-        else
-            ext4_dir_entry_ll_set_entry_length(tmp,
-                    block_size - offset);
-
-        offset += sort_array[i].rec_len;
-    }
-
-    /* Second part - to the new block */
-    offset = 0;
-    for (i = mid; i < idx; ++i) {
-        ptr = new_data_block_tmp.data + offset;
-        memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len);
-
-        struct ext4_directory_entry_ll *tmp = ptr;
-        if (i < (idx - 1))
-            ext4_dir_entry_ll_set_entry_length(tmp,
-                    sort_array[i].rec_len);
-        else
-            ext4_dir_entry_ll_set_entry_length(tmp,
-                    block_size - offset);
-
-        offset += sort_array[i].rec_len;
-    }
-
-    /* Do some steps to finish operation */
-    old_data_block->dirty = true;
-    new_data_block_tmp.dirty = true;
-
-    free(sort_array);
-    free(entry_buffer);
-
-    ext4_dir_dx_insert_entry(index_block, new_hash + continued,
-            new_iblock);
-
-    *new_data_block = new_data_block_tmp;
-
-    return EOK;
-}
-
-/** Split index node and maybe some parent nodes in the tree hierarchy.
- *
- * @param inode_ref Directory i-node
- * @param dx_blocks Array with path from root to leaf node
- * @param dx_block  Leaf block to be split if needed
- *
- * @return Error code
- *
- */
-static int ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref,
-        struct  ext4_directory_dx_block *dx_blocks,
-        struct ext4_directory_dx_block *dx_block)
-{
-    struct ext4_directory_dx_entry *entries;
-    if (dx_block == dx_blocks)
-        entries =
-                ((struct  ext4_directory_dx_root *) dx_block->block.data)->entries;
-    else
-        entries =
-                ((struct ext4_directory_dx_node *) dx_block->block.data)->entries;
-
-    struct ext4_directory_dx_countlimit *countlimit =
-            (struct ext4_directory_dx_countlimit *) entries;
-
-    uint16_t leaf_limit =
-            ext4_dir_dx_countlimit_get_limit(countlimit);
-    uint16_t leaf_count =
-            ext4_dir_dx_countlimit_get_count(countlimit);
-
-    /* Check if is necessary to split index block */
-    if (leaf_limit == leaf_count) {
-        size_t levels = dx_block - dx_blocks;
-
-        struct ext4_directory_dx_entry *root_entries =
-                ((struct ext4_directory_dx_root *) dx_blocks[0].block.data)->entries;
-
-        struct ext4_directory_dx_countlimit *root_countlimit =
-                (struct ext4_directory_dx_countlimit *) root_entries;
-        uint16_t root_limit =
-                ext4_dir_dx_countlimit_get_limit(root_countlimit);
-        uint16_t root_count =
-                ext4_dir_dx_countlimit_get_count(root_countlimit);
-
-        /* Linux limitation */
-        if ((levels > 0) && (root_limit == root_count))
-            return ENOSPC;
-
-        /* Add new block to directory */
-        uint32_t new_fblock;
-        uint32_t new_iblock;
-        int rc = ext4_fs_append_inode_block(inode_ref,
-                &new_fblock, &new_iblock);
-        if (rc != EOK)
-            return rc;
-
-        /* load new block */
-        struct ext4_block new_block;
-        rc = ext4_block_get(inode_ref->fs->bdev, &new_block,
-                new_fblock);
-        if (rc != EOK)
-            return rc;
-
-        struct ext4_directory_dx_node  *new_node 	= (void *)new_block.data;
-        struct ext4_directory_dx_entry *new_entries = new_node->entries;
-
-        uint32_t block_size =
-                ext4_sb_get_block_size(&inode_ref->fs->sb);
-
-        /* Split leaf node */
-        if (levels > 0) {
-            uint32_t count_left = leaf_count / 2;
-            uint32_t count_right = leaf_count - count_left;
-            uint32_t hash_right =
-                    ext4_dir_dx_entry_get_hash(entries + count_left);
-
-            /* Copy data to new node */
-            memcpy((void *) new_entries, (void *) (entries + count_left),
-                    count_right * sizeof(struct ext4_directory_dx_entry));
-
-            /* Initialize new node */
-            struct ext4_directory_dx_countlimit *left_countlimit =
-                    (struct ext4_directory_dx_countlimit *) entries;
-            struct ext4_directory_dx_countlimit *right_countlimit =
-                    (struct ext4_directory_dx_countlimit *) new_entries;
-
-            ext4_dir_dx_countlimit_set_count(left_countlimit, count_left);
-            ext4_dir_dx_countlimit_set_count(right_countlimit, count_right);
-
-            uint32_t entry_space =
-                    block_size - sizeof(struct ext4_fake_directory_entry);
-            uint32_t node_limit =
-                    entry_space / sizeof(struct ext4_directory_dx_entry);
-            ext4_dir_dx_countlimit_set_limit(right_countlimit, node_limit);
-
-            /* Which index block is target for new entry */
-            uint32_t position_index = (dx_block->position - dx_block->entries);
-            if (position_index >= count_left) {
-                dx_block->block.dirty = true;
-
-                struct ext4_block block_tmp = dx_block->block;
-
-
-                dx_block->block = new_block;
-
-                dx_block->position =
-                        new_entries + position_index - count_left;
-                dx_block->entries = new_entries;
-
-                new_block = block_tmp;
-            }
-
-            /* Finally insert new entry */
-            ext4_dir_dx_insert_entry(dx_blocks, hash_right, new_iblock);
-
-            return ext4_block_set(inode_ref->fs->bdev, &new_block);
-        } else {
-            /* Create second level index */
-
-            /* Copy data from root to child block */
-            memcpy((void *) new_entries, (void *) entries,
-                    leaf_count * sizeof(struct ext4_directory_dx_entry));
-
-            struct ext4_directory_dx_countlimit *new_countlimit =
-                    (struct ext4_directory_dx_countlimit *) new_entries;
-
-            uint32_t entry_space =
-                    block_size - sizeof(struct ext4_fake_directory_entry);
-            uint32_t node_limit =
-                    entry_space / sizeof(struct ext4_directory_dx_entry);
-            ext4_dir_dx_countlimit_set_limit(new_countlimit, node_limit);
-
-            /* Set values in root node */
-            struct ext4_directory_dx_countlimit *new_root_countlimit =
-                    (struct ext4_directory_dx_countlimit *) entries;
-
-            ext4_dir_dx_countlimit_set_count(new_root_countlimit, 1);
-            ext4_dir_dx_entry_set_block(entries, new_iblock);
-
-            ((struct ext4_directory_dx_root *)
-                    dx_blocks[0].block.data)->info.indirect_levels = 1;
-
-            /* Add new entry to the path */
-            dx_block = dx_blocks + 1;
-            dx_block->position = dx_block->position - entries + new_entries;
-            dx_block->entries = new_entries;
-            dx_block->block = new_block;
-        }
-    }
-
-    return EOK;
-}
-
-int 	ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
-        struct ext4_inode_ref *child, const char *name)
-{
-    int rc2 = EOK;
-
-    /* Get direct block 0 (index root) */
-    uint32_t root_block_addr;
-    int rc = ext4_fs_get_inode_data_block_index(parent, 0,
-            &root_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    struct ext4_fs *fs = parent->fs;
-    struct ext4_block root_block;
-
-    rc = ext4_block_get(fs->bdev, &root_block, root_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Initialize hinfo structure (mainly compute hash) */
-    uint32_t name_len = strlen(name);
-    struct ext4_hash_info hinfo;
-    rc = ext4_dir_hinfo_init(&hinfo, &root_block, &fs->sb,
-            name_len, name);
-    if (rc != EOK) {
-        ext4_block_set(fs->bdev, &root_block);
-        return EXT4_ERR_BAD_DX_DIR;
-    }
-
-    /*
-     * Hardcoded number 2 means maximum height of index
-     * tree defined in Linux.
-     */
-    struct ext4_directory_dx_block dx_blocks[2];
-    struct ext4_directory_dx_block *dx_block;
-    struct ext4_directory_dx_block *dx_it;
-
-    rc = ext4_dir_dx_get_leaf(&hinfo, parent, &root_block,
-            &dx_block, dx_blocks);
-    if (rc != EOK) {
-        rc = EXT4_ERR_BAD_DX_DIR;
-        goto release_index;
-    }
-
-    /* Try to insert to existing data block */
-    uint32_t leaf_block_idx =
-            ext4_dir_dx_entry_get_block(dx_block->position);
-    uint32_t leaf_block_addr;
-    rc = ext4_fs_get_inode_data_block_index(parent, leaf_block_idx,
-            &leaf_block_addr);
-    if (rc != EOK)
-        goto release_index;
-
-    struct ext4_block target_block;
-    rc = ext4_block_get(fs->bdev, &target_block, leaf_block_addr);
-    if (rc != EOK)
-        goto release_index;
-
-    /* Check if insert operation passed */
-    rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child,
-            name, name_len);
-    if (rc == EOK)
-        goto release_target_index;
-
-    /*
-     * Check if there is needed to split index node
-     * (and recursively also parent nodes)
-     */
-    rc = ext4_dir_dx_split_index(parent, dx_blocks, dx_block);
-    if (rc != EOK)
-        goto release_target_index;
-
-    /* Split entries to two blocks (includes sorting by hash value) */
-    struct ext4_block new_block;
-    rc = ext4_dir_dx_split_data(parent, &hinfo, &target_block,
-            dx_block, &new_block);
-    if (rc != EOK) {
-        rc2 = rc;
-        goto release_target_index;
-    }
-
-    /* Where to save new entry */
-    uint32_t new_block_hash =
-            ext4_dir_dx_entry_get_hash(dx_block->position + 1);
-    if (hinfo.hash >= new_block_hash)
-        rc = ext4_dir_try_insert_entry(&fs->sb, &new_block,
-                child, name, name_len);
-    else
-        rc = ext4_dir_try_insert_entry(&fs->sb, &target_block,
-                child, name, name_len);
-
-    /* Cleanup */
-    rc = ext4_block_set(fs->bdev, &new_block);
-    if (rc != EOK)
-        return rc;
-
-    /* Cleanup operations */
-
-    release_target_index:
-    rc2 = rc;
-
-    rc = ext4_block_set(fs->bdev, &target_block);
-    if (rc != EOK)
-        return rc;
-
-    release_index:
-    if (rc != EOK)
-        rc2 = rc;
-
-    dx_it = dx_blocks;
-
-    while (dx_it <= dx_block) {
-        rc = ext4_block_set(fs->bdev, &dx_it->block);
-        if (rc != EOK)
-            return rc;
-
-        dx_it++;
-    }
-
-    return rc2;
-}
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_dir_idx.h
+++ /dev/null
@@ -1,103 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_dir_idx.h
- * @brief Directory indexing procedures.
- */
-
-#ifndef EXT4_DIR_IDX_H_
-#define EXT4_DIR_IDX_H_
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-
-uint8_t ext4_dir_dx_root_info_get_hash_version(
-        struct ext4_directory_dx_root_info *root_info);
-void 	ext4_dir_dx_root_info_set_hash_version(
-        struct ext4_directory_dx_root_info  *root_info, uint8_t v);
-
-uint8_t ext4_dir_dx_root_info_get_info_length(
-        struct ext4_directory_dx_root_info *root_info);
-void 	ext4_dir_dx_root_info_set_info_length(
-        struct ext4_directory_dx_root_info  *root_info, uint8_t len);
-
-uint8_t ext4_dir_dx_root_info_get_indirect_levels(
-        struct ext4_directory_dx_root_info *root_info);
-void 	ext4_dir_dx_root_info_set_indirect_levels(
-        struct ext4_directory_dx_root_info *root_info, uint8_t lvl);
-
-
-
-uint16_t ext4_dir_dx_countlimit_get_limit(
-        struct ext4_directory_dx_countlimit *climit);
-void 	ext4_dir_dx_countlimit_set_limit(
-        struct ext4_directory_dx_countlimit *climit, uint16_t limit);
-
-uint16_t ext4_dir_dx_countlimit_get_count(
-        struct ext4_directory_dx_countlimit *climit);
-void 	ext4_dir_dx_countlimit_set_count(
-        struct ext4_directory_dx_countlimit *climit, uint16_t count);
-
-
-uint32_t ext4_dir_dx_entry_get_hash(
-        struct ext4_directory_dx_entry *entry);
-void ext4_dir_dx_entry_set_hash(
-        struct ext4_directory_dx_entry *entry, uint32_t hash);
-
-uint32_t ext4_dir_dx_entry_get_block(
-        struct ext4_directory_dx_entry *entry);
-void 	ext4_dir_dx_entry_set_block(
-        struct ext4_directory_dx_entry *entry, uint32_t block);
-
-
-int 	ext4_dir_dx_init(struct ext4_inode_ref *dir);
-
-int 	ext4_dir_dx_find_entry(struct ext4_directory_search_result * result,
-        struct ext4_inode_ref *inode_ref, size_t name_len, const char *name);
-
-int 	ext4_dir_dx_add_entry(struct ext4_inode_ref *parent,
-        struct ext4_inode_ref *child, const char *name);
-
-#endif /* EXT4_DIR_IDX_H_ */
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_errno.h
+++ /dev/null
@@ -1,92 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_errno.h
- * @brief Error codes.
- */
-#ifndef EXT4_ERRNO_H_
-#define EXT4_ERRNO_H_
-
-#include <ext4_config.h>
-
-#ifndef CONFIG_HAVE_OWN_ERRNO
-#include <errno.h>
-#else
-#define	EPERM		 1	/* Operation not permitted */
-#define	ENOENT		 2	/* No such file or directory */
-#define	ESRCH		 3	/* No such process */
-#define	EINTR		 4	/* Interrupted system call */
-#define	EIO			 5	/* I/O error */
-#define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Argument list too long */
-#define	ENOEXEC		 8	/* Exec format error */
-#define	EBADF		 9	/* Bad file number */
-#define	ECHILD		10	/* No child processes */
-#define	EAGAIN		11	/* Try again */
-#define	ENOMEM		12	/* Out of memory */
-#define	EACCES		13	/* Permission denied */
-#define	EFAULT		14	/* Bad address */
-#define	ENOTBLK		15	/* Block device required */
-#define	EBUSY		16	/* Device or resource busy */
-#define	EEXIST		17	/* File exists */
-#define	EXDEV		18	/* Cross-device link */
-#define	ENODEV		19	/* No such device */
-#define	ENOTDIR		20	/* Not a directory */
-#define	EISDIR		21	/* Is a directory */
-#define	EINVAL		22	/* Invalid argument */
-#define	ENFILE		23	/* File table overflow */
-#define	EMFILE		24	/* Too many open files */
-#define	ENOTTY		25	/* Not a typewriter */
-#define	ETXTBSY		26	/* Text file busy */
-#define	EFBIG		27	/* File too large */
-#define	ENOSPC		28	/* No space left on device */
-#define	ESPIPE		29	/* Illegal seek */
-#define	EROFS		30	/* Read-only file system */
-#define	EMLINK		31	/* Too many links */
-#define	EPIPE		32	/* Broken pipe */
-#define	EDOM		33	/* Math argument out of domain of func */
-#define	ERANGE		34	/* Math result not representable */
-
-#define	ENOTSUP		95
-#endif
-
-/**@brief	OK return value*/
-#ifndef EOK
-#define EOK			0
-#endif
-
-#endif /* EXT4_ERRNO_H_ */
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_fs.c
+++ /dev/null
@@ -1,1189 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_fs.c
- * @brief More complex filesystem functions.
- */
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-#include <ext4_fs.h>
-#include <ext4_errno.h>
-#include <ext4_blockdev.h>
-#include <ext4_super.h>
-#include <ext4_debug.h>
-#include <ext4_block_group.h>
-#include <ext4_balloc.h>
-#include <ext4_bitmap.h>
-#include <ext4_inode.h>
-#include <ext4_ialloc.h>
-#include <string.h>
-
-int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev)
-{
-    int r, i;
-    uint16_t tmp;
-    uint32_t bsize;
-    bool read_only = false;
-
-    ext4_assert(fs && bdev);
-
-    fs->bdev = bdev;
-
-    r = ext4_sb_read(fs->bdev, &fs->sb);
-    if(r != EOK)
-        return r;
-
-    if(!ext4_sb_check(&fs->sb))
-        return ENOTSUP;
-
-    bsize = ext4_sb_get_block_size(&fs->sb);
-    if (bsize > EXT4_MAX_BLOCK_SIZE)
-        return ENXIO;
-
-    r = ext4_fs_check_features(fs, &read_only);
-    if(r != EOK)
-        return r;
-
-    if(read_only)
-        return ENOTSUP;
-
-    /* Compute limits for indirect block levels */
-    uint32_t blocks_id = bsize / sizeof(uint32_t);
-
-    fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT;
-    fs->inode_blocks_per_level[0] = 1;
-
-    for (i = 1; i < 4; i++) {
-        fs->inode_blocks_per_level[i] = fs->inode_blocks_per_level[i - 1] *
-                blocks_id;
-        fs->inode_block_limits[i] = fs->inode_block_limits[i - 1] +
-                fs->inode_blocks_per_level[i];
-    }
-
-    /*Validate FS*/
-    tmp = ext4_get16(&fs->sb, state);
-    if (tmp & EXT4_SUPERBLOCK_STATE_ERROR_FS) {
-        ext4_dprintf(EXT4_DEBUG_FS,
-                "Filesystem was not cleanly unmounted before \n");
-    }
-
-    /* Mark system as mounted */
-    ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_ERROR_FS);
-    r = ext4_sb_write(fs->bdev, &fs->sb);
-    if (r != EOK)
-        return r;
-
-
-    /*Update mount count*/
-    ext4_set16(&fs->sb, mount_count, ext4_get16(&fs->sb, mount_count) + 1);
-
-    return r;
-}
-
-
-int ext4_fs_fini(struct ext4_fs *fs)
-{
-    ext4_assert(fs);
-
-    /*Set superblock state*/
-    ext4_set16(&fs->sb, state, EXT4_SUPERBLOCK_STATE_VALID_FS);
-
-    return ext4_sb_write(fs->bdev, &fs->sb);
-}
-
-int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only)
-{
-    ext4_assert(fs && read_only);
-
-    if(ext4_get32(&fs->sb, rev_level) == 0){
-        *read_only = false;
-        return EOK;
-    }
-
-    /*Check features_incompatible*/
-    if ((ext4_get32(&fs->sb, features_incompatible) &
-            (~EXT4_FEATURE_INCOMPAT_SUPP)) )
-        return ENOTSUP;
-
-
-    /*Check features_read_only*/
-    if ((ext4_get32(&fs->sb, features_read_only) &
-            (~EXT4_FEATURE_RO_COMPAT_SUPP))){
-        *read_only = true;
-        return EOK;
-    }
-
-    *read_only = false;
-
-    return EOK;
-}
-
-uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr)
-{
-    ext4_assert(baddr);
-    if(ext4_get32(s, first_data_block))
-        baddr--;
-
-    return  baddr % ext4_get32(s, blocks_per_group);
-}
-
-
-
-uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
-    uint32_t bgid)
-{
-    if(ext4_get32(s, first_data_block))
-        index++;
-
-    return ext4_get32(s, blocks_per_group) * bgid + index;
-}
-
-
-
-
-static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)
-{
-    uint32_t i;
-    uint32_t bitmap_block_addr = ext4_bg_get_block_bitmap(
-            bg_ref->block_group, &bg_ref->fs->sb);
-
-    struct ext4_block block_bitmap;
-    int rc = ext4_block_get(bg_ref->fs->bdev, &block_bitmap,
-            bitmap_block_addr);
-    if (rc != EOK)
-        return rc;
-
-
-    memset(block_bitmap.data, 0, ext4_sb_get_block_size(&bg_ref->fs->sb));
-
-    /* Determine first block and first data block in group */
-    uint32_t first_idx = 0;
-
-    uint32_t first_data = ext4_balloc_get_first_data_block_in_group(
-            &bg_ref->fs->sb, bg_ref);
-    uint32_t first_data_idx = ext4_fs_baddr2_index_in_group(
-            &bg_ref->fs->sb, first_data);
-
-    /*Set bits from to first block to first data block - 1 to one (allocated)*/
-    /*TODO: Optimize it*/
-    for (i = first_idx; i < first_data_idx; ++i)
-        ext4_bmap_bit_set(block_bitmap.data, i);
-
-
-    block_bitmap.dirty = true;
-
-    /* Save bitmap */
-    return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
-}
-
-static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref)
-{
-    /* Load bitmap */
-    uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(
-            bg_ref->block_group, &bg_ref->fs->sb);
-
-    struct ext4_block block_bitmap;
-    int rc = ext4_block_get(bg_ref->fs->bdev, &block_bitmap,
-            bitmap_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Initialize all bitmap bits to zero */
-    uint32_t block_size = ext4_sb_get_block_size(&bg_ref->fs->sb);
-    uint32_t inodes_per_group = ext4_get32(&bg_ref->fs->sb, inodes_per_group);
-
-    memset(block_bitmap.data, 0, (inodes_per_group + 7) / 8);
-
-    uint32_t start_bit = inodes_per_group;
-    uint32_t end_bit = block_size * 8;
-
-    uint32_t i;
-    for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
-        ext4_bmap_bit_set(block_bitmap.data, i);
-
-    if (i < end_bit)
-        memset(block_bitmap.data + (i >> 3), 0xff, (end_bit - i) >> 3);
-
-    block_bitmap.dirty = true;
-
-    /* Save bitmap */
-    return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
-}
-
-static int ext4_fs_init_inode_table(struct ext4_block_group_ref *bg_ref)
-{
-    struct ext4_sblock *sb = &bg_ref->fs->sb;
-
-    uint32_t inode_size 	  = ext4_get32(sb, inode_size);
-    uint32_t block_size 	  = ext4_sb_get_block_size(sb);
-    uint32_t inodes_per_block = block_size / inode_size;
-    uint32_t inodes_in_group  = ext4_inodes_in_group_cnt(sb, bg_ref->index);
-    uint32_t table_blocks = inodes_in_group / inodes_per_block;
-    uint32_t fblock;
-
-    if (inodes_in_group % inodes_per_block)
-        table_blocks++;
-
-    /* Compute initialization bounds */
-    uint32_t first_block = ext4_bg_get_inode_table_first_block(
-            bg_ref->block_group, sb);
-
-    uint32_t last_block = first_block + table_blocks - 1;
-
-    /* Initialization of all itable blocks */
-    for (fblock = first_block; fblock <= last_block; ++fblock) {
-
-        struct ext4_block block;
-        int rc = ext4_block_get(bg_ref->fs->bdev, &block, fblock);
-        if (rc != EOK)
-            return rc;
-
-        memset(block.data, 0, block_size);
-        block.dirty = true;
-
-        ext4_block_set(bg_ref->fs->bdev, &block);
-        if (rc != EOK)
-            return rc;
-    }
-
-    return EOK;
-}
-
-
-int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
-    struct ext4_block_group_ref *ref)
-{
-    /* Compute number of descriptors, that fits in one data block */
-    uint32_t dsc_per_block = ext4_sb_get_block_size(&fs->sb) /
-            ext4_sb_get_desc_size(&fs->sb);
-
-    /* Block group descriptor table starts at the next block after superblock */
-    uint64_t block_id = ext4_get32(&fs->sb, first_data_block) + 1;
-
-    /* Find the block containing the descriptor we are looking for */
-    block_id += bgid / dsc_per_block;
-    uint32_t offset = (bgid % dsc_per_block) *
-            ext4_sb_get_desc_size(&fs->sb);
-
-
-    int rc = ext4_block_get(fs->bdev, &ref->block, block_id);
-    if (rc != EOK)
-        return rc;
-
-    ref->block_group = (void *)(ref->block.data + offset);
-    ref->fs = fs;
-    ref->index = bgid;
-    ref->dirty = false;
-
-    if (ext4_bg_has_flag(ref->block_group,
-            EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
-        rc = ext4_fs_init_block_bitmap(ref);
-        if (rc != EOK) {
-            ext4_block_set(fs->bdev, &ref->block);
-            return rc;
-        }
-        ext4_bg_clear_flag(ref->block_group,
-            EXT4_BLOCK_GROUP_BLOCK_UNINIT);
-
-        ref->dirty = true;
-    }
-
-    if (ext4_bg_has_flag(ref->block_group,
-            EXT4_BLOCK_GROUP_INODE_UNINIT)) {
-        rc = ext4_fs_init_inode_bitmap(ref);
-        if (rc != EOK) {
-            ext4_block_set(ref->fs->bdev, &ref->block);
-            return rc;
-        }
-
-        ext4_bg_clear_flag(ref->block_group,
-            EXT4_BLOCK_GROUP_INODE_UNINIT);
-
-        if (!ext4_bg_has_flag(ref->block_group,
-                EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
-            rc = ext4_fs_init_inode_table(ref);
-            if (rc != EOK){
-                ext4_block_set(fs->bdev, &ref->block);
-                return rc;
-            }
-
-            ext4_bg_set_flag(ref->block_group,
-                EXT4_BLOCK_GROUP_ITABLE_ZEROED);
-        }
-
-        ref->dirty = true;
-    }
-
-    return EOK;
-}
-
-static uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid,
-    struct ext4_bgroup *bg)
-{
-    /* If checksum not supported, 0 will be returned */
-    uint16_t crc = 0;
-
-    /* Compute the checksum only if the filesystem supports it */
-    if (ext4_sb_check_read_only(sb,
-            EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-        void *base = bg;
-        void *checksum = &bg->checksum;
-
-        uint32_t offset = (uint32_t) (checksum - base);
-
-        /* Convert block group index to little endian */
-        uint32_t le_group = to_le32(bgid);
-
-        /* Initialization */
-        crc = ext4_bg_crc16(~0, sb->uuid, sizeof(sb->uuid));
-
-        /* Include index of block group */
-        crc = ext4_bg_crc16(crc, (uint8_t *) &le_group, sizeof(le_group));
-
-        /* Compute crc from the first part (stop before checksum field) */
-        crc = ext4_bg_crc16(crc, (uint8_t *) bg, offset);
-
-        /* Skip checksum */
-        offset += sizeof(bg->checksum);
-
-        /* Checksum of the rest of block group descriptor */
-        if ((ext4_sb_check_feature_incompatible(sb,
-                EXT4_FEATURE_INCOMPAT_64BIT)) &&
-                (offset < ext4_sb_get_desc_size(sb)))
-
-            crc = ext4_bg_crc16(crc, ((uint8_t *) bg) + offset,
-                    ext4_sb_get_desc_size(sb) - offset);
-    }
-    return crc;
-}
-
-int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref)
-{
-    /* Check if reference modified */
-    if (ref->dirty) {
-        /* Compute new checksum of block group */
-        uint16_t checksum =
-                ext4_fs_bg_checksum(&ref->fs->sb, ref->index,
-                        ref->block_group);
-
-        ref->block_group->checksum = to_le16(checksum);
-
-        /* Mark block dirty for writing changes to physical device */
-        ref->block.dirty = true;
-    }
-
-    /* Put back block, that contains block group descriptor */
-    return ext4_block_set(ref->fs->bdev, &ref->block);
-}
-
-int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
-    struct ext4_inode_ref *ref)
-{
-    /* Compute number of i-nodes, that fits in one data block */
-    uint32_t inodes_per_group = ext4_get32(&fs->sb, inodes_per_group);
-
-    /*
-     * Inode numbers are 1-based, but it is simpler to work with 0-based
-     * when computing indices
-     */
-    index -= 1;
-    uint32_t block_group = index / inodes_per_group;
-    uint32_t offset_in_group = index % inodes_per_group;
-
-    /* Load block group, where i-node is located */
-    struct ext4_block_group_ref bg_ref;
-
-    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
-    if (rc != EOK) {
-        return rc;
-    }
-
-    /* Load block address, where i-node table is located */
-    uint32_t inode_table_start =
-            ext4_bg_get_inode_table_first_block(bg_ref.block_group,
-                    &fs->sb);
-
-    /* Put back block group reference (not needed more) */
-    rc = ext4_fs_put_block_group_ref(&bg_ref);
-    if (rc != EOK) {
-        return rc;
-    }
-
-    /* Compute position of i-node in the block group */
-    uint16_t inode_size = ext4_get16(&fs->sb, inode_size);
-    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
-    uint32_t byte_offset_in_group = offset_in_group * inode_size;
-
-    /* Compute block address */
-    uint64_t block_id = inode_table_start +
-            (byte_offset_in_group / block_size);
-
-
-    rc = ext4_block_get(fs->bdev, &ref->block, block_id);
-    if (rc != EOK) {
-        return rc;
-    }
-
-    /* Compute position of i-node in the data block */
-    uint32_t offset_in_block = byte_offset_in_group % block_size;
-    ref->inode = (struct ext4_inode *)(ref->block.data + offset_in_block);
-
-    /* We need to store the original value of index in the reference */
-    ref->index = index + 1;
-    ref->fs = fs;
-    ref->dirty = false;
-
-    return EOK;
-}
-
-int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref)
-{
-    /* Check if reference modified */
-    if (ref->dirty) {
-        /* Mark block dirty for writing changes to physical device */
-        ref->block.dirty = true;
-    }
-
-    /* Put back block, that contains i-node */
-    return  ext4_block_set(ref->fs->bdev, &ref->block);
-}
-
-int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
-    bool is_directory)
-{
-    /* Check if newly allocated i-node will be a directory */
-    uint32_t i;
-    bool is_dir;
-
-    is_dir = is_directory;
-
-    /* Allocate inode by allocation algorithm */
-    uint32_t index;
-    int rc = ext4_ialloc_alloc_inode(fs, &index, is_dir);
-    if (rc != EOK)
-        return rc;
-
-    /* Load i-node from on-disk i-node table */
-    rc = ext4_fs_get_inode_ref(fs, index, inode_ref);
-    if (rc != EOK) {
-        ext4_ialloc_free_inode(fs, index, is_dir);
-        return rc;
-    }
-
-    /* Initialize i-node */
-    struct ext4_inode *inode = inode_ref->inode;
-
-    uint16_t mode;
-    if (is_dir) {
-        /*
-         * Default directory permissions to be compatible with other systems
-         * 0777 (octal) == rwxrwxrwx
-         */
-
-        mode = 0777;
-        mode |= EXT4_INODE_MODE_DIRECTORY;
-        ext4_inode_set_mode(&fs->sb, inode, mode);
-        ext4_inode_set_links_count(inode, 1);  /* '.' entry */
-
-    } else {
-        /*
-         * Default file permissions to be compatible with other systems
-         * 0666 (octal) == rw-rw-rw-
-         */
-
-        mode = 0666;
-        mode |= EXT4_INODE_MODE_FILE;
-        ext4_inode_set_mode(&fs->sb, inode, mode);
-        ext4_inode_set_links_count(inode, 0);
-    }
-
-    ext4_inode_set_uid(inode, 0);
-    ext4_inode_set_gid(inode, 0);
-    ext4_inode_set_size(inode, 0);
-    ext4_inode_set_access_time(inode, 		0);
-    ext4_inode_set_change_inode_time(inode, 0);
-    ext4_inode_set_modification_time(inode, 0);
-    ext4_inode_set_deletion_time(inode, 	0);
-    ext4_inode_set_blocks_count(&fs->sb, inode, 0);
-    ext4_inode_set_flags(inode, 0);
-    ext4_inode_set_generation(inode, 0);
-
-    /* Reset blocks array */
-    for (i = 0; i < EXT4_INODE_BLOCKS; i++)
-        inode->blocks[i] = 0;
-
-#if 0
-    /* Initialize extents if needed */
-    if (ext4_sb_check_feature_incompatible(
-            &fs->sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
-        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS);
-
-
-        /* Initialize extent root header */
-        ext4_extent_header_t *header = ext4_inode_get_extent_header(inode);
-        ext4_extent_header_set_depth(header, 0);
-        ext4_extent_header_set_entries_count(header, 0);
-        ext4_extent_header_set_generation(header, 0);
-        ext4_extent_header_set_magic(header, EXT4_EXTENT_MAGIC);
-
-        uint16_t max_entries = (EXT4_INODE_BLOCKS * sizeof(uint32_t) -
-                sizeof(ext4_extent_header_t)) / sizeof(ext4_extent_t);
-
-        ext4_extent_header_set_max_entries_count(header, max_entries);
-    }
-#endif
-
-    inode_ref->dirty = true;
-
-    return EOK;
-}
-
-int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref)
-{
-    struct ext4_fs *fs = inode_ref->fs;
-    uint32_t offset;
-    uint32_t suboffset;
-    /* For extents must be data block destroyed by other way */
-    if ((ext4_sb_check_feature_incompatible(&fs->sb,
-            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
-            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))){
-        /* Data structures are released during truncate operation... */
-        goto finish;
-    }
-
-    /* Release all indirect (no data) blocks */
-
-    /* 1) Single indirect */
-    uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);
-    if (fblock != 0) {
-        int rc = ext4_balloc_free_block(inode_ref, fblock);
-        if (rc != EOK)
-            return rc;
-
-        ext4_inode_set_indirect_block(inode_ref->inode, 0, 0);
-    }
-
-    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
-    uint32_t count = block_size / sizeof(uint32_t);
-
-    struct	ext4_block  block;
-
-    /* 2) Double indirect */
-    fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1);
-    if (fblock != 0) {
-        int rc = ext4_block_get(fs->bdev, &block, fblock);
-        if (rc != EOK)
-            return rc;
-
-        uint32_t ind_block;
-        for (offset = 0; offset < count; ++offset) {
-            ind_block = to_le32(((uint32_t *) block.data)[offset]);
-
-            if (ind_block != 0) {
-                rc = ext4_balloc_free_block(inode_ref, ind_block);
-                if (rc != EOK) {
-                    ext4_block_set(fs->bdev, &block);
-                    return rc;
-                }
-            }
-        }
-
-        ext4_block_set(fs->bdev, &block);
-        rc = ext4_balloc_free_block(inode_ref, fblock);
-        if (rc != EOK)
-            return rc;
-
-        ext4_inode_set_indirect_block(inode_ref->inode, 1, 0);
-    }
-
-    /* 3) Tripple indirect */
-    struct	ext4_block  subblock;
-    fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2);
-    if (fblock != 0) {
-        int rc = ext4_block_get(fs->bdev, &block, fblock);
-        if (rc != EOK)
-            return rc;
-
-        uint32_t ind_block;
-        for ( offset = 0; offset < count; ++offset) {
-            ind_block = to_le32(((uint32_t *) block.data)[offset]);
-
-            if (ind_block != 0) {
-                rc = ext4_block_get(fs->bdev, &subblock, ind_block);
-                if (rc != EOK) {
-                    ext4_block_set(fs->bdev, &block);
-                    return rc;
-                }
-
-                uint32_t ind_subblock;
-                for (suboffset = 0; suboffset < count;
-                        ++suboffset) {
-                    ind_subblock = to_le32(((uint32_t *)
-                            subblock.data)[suboffset]);
-
-                    if (ind_subblock != 0) {
-                        rc = ext4_balloc_free_block(inode_ref, ind_subblock);
-                        if (rc != EOK) {
-                            ext4_block_set(fs->bdev, &subblock);
-                            ext4_block_set(fs->bdev, &block);
-                            return rc;
-                        }
-                    }
-                }
-
-                ext4_block_set(fs->bdev, &subblock);
-
-
-                rc = ext4_balloc_free_block(inode_ref, ind_block);
-                if (rc != EOK) {
-                    ext4_block_set(fs->bdev, &block);
-                    return rc;
-                }
-            }
-        }
-
-        ext4_block_set(fs->bdev, &block);
-        rc = ext4_balloc_free_block(inode_ref, fblock);
-        if (rc != EOK)
-            return rc;
-
-        ext4_inode_set_indirect_block(inode_ref->inode, 2, 0);
-    }
-
-    finish:
-    /* Mark inode dirty for writing to the physical device */
-    inode_ref->dirty = true;
-
-    /* Free block with extended attributes if present */
-    uint32_t xattr_block = ext4_inode_get_file_acl(
-            inode_ref->inode, &fs->sb);
-    if (xattr_block) {
-        int rc = ext4_balloc_free_block(inode_ref, xattr_block);
-        if (rc != EOK)
-            return rc;
-
-        ext4_inode_set_file_acl(inode_ref->inode, &fs->sb, 0);
-    }
-
-    /* Free inode by allocator */
-    int rc;
-    if (ext4_inode_is_type(&fs->sb, inode_ref->inode,
-            EXT4_INODE_MODE_DIRECTORY))
-        rc = ext4_ialloc_free_inode(fs, inode_ref->index, true);
-    else
-        rc = ext4_ialloc_free_inode(fs, inode_ref->index, false);
-
-    return rc;
-}
-
-int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref,
-    uint64_t new_size)
-{
-    struct ext4_sblock *sb = &inode_ref->fs->sb;
-    uint32_t i;
-
-    /* Check flags, if i-node can be truncated */
-    if (!ext4_inode_can_truncate(sb, inode_ref->inode))
-        return EINVAL;
-
-    /* If sizes are equal, nothing has to be done. */
-    uint64_t old_size = ext4_inode_get_size(sb, inode_ref->inode);
-    if (old_size == new_size)
-        return EOK;
-
-    /* It's not suppported to make the larger file by truncate operation */
-    if (old_size < new_size)
-        return EINVAL;
-
-    /* Compute how many blocks will be released */
-    uint64_t size_diff = old_size - new_size;
-    uint32_t block_size  = ext4_sb_get_block_size(sb);
-    uint32_t diff_blocks_count = size_diff / block_size;
-    if (size_diff % block_size != 0)
-        diff_blocks_count++;
-
-    uint32_t old_blocks_count = old_size / block_size;
-    if (old_size % block_size != 0)
-        old_blocks_count++;
-
-    if ((ext4_sb_check_feature_incompatible(sb,
-            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
-            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
-#if 0
-        /* Extents require special operation */
-        int rc = ext4_extent_release_blocks_from(inode_ref,
-                old_blocks_count - diff_blocks_count);
-        if (rc != EOK)
-            return rc;
-#endif
-    } else {
-        /* Release data blocks from the end of file */
-
-        /* Starting from 1 because of logical blocks are numbered from 0 */
-        for (i = 1; i <= diff_blocks_count; ++i) {
-            int rc = ext4_fs_release_inode_block(inode_ref,
-                    old_blocks_count - i);
-            if (rc != EOK)
-                return rc;
-        }
-    }
-
-    /* Update i-node */
-    ext4_inode_set_size(inode_ref->inode, new_size);
-    inode_ref->dirty = true;
-
-    return EOK;
-}
-
-int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref,
-    uint64_t iblock, uint32_t *fblock)
-{
-    struct ext4_fs *fs = inode_ref->fs;
-
-    /* For empty file is situation simple */
-    if (ext4_inode_get_size(&fs->sb, inode_ref->inode) == 0) {
-        *fblock = 0;
-        return EOK;
-    }
-
-    uint32_t current_block;
-
-    /* Handle i-node using extents */
-    if ((ext4_sb_check_feature_incompatible(&fs->sb,
-            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
-            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
-
-#if 0
-        int rc = ext4_extent_find_block(inode_ref, iblock, &current_block);
-        if (rc != EOK)
-            return rc;
-
-        *fblock = current_block;
-        return EOK;
-#endif
-    }
-
-    struct ext4_inode *inode = inode_ref->inode;
-
-    /* Direct block are read directly from array in i-node structure */
-    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
-        current_block = ext4_inode_get_direct_block(inode, (uint32_t) iblock);
-        *fblock = current_block;
-        return EOK;
-    }
-
-    /* Determine indirection level of the target block */
-    unsigned int level = 0;
-    unsigned int i;
-    for (i = 1; i < 4; i++) {
-        if (iblock < fs->inode_block_limits[i]) {
-            level = i;
-            break;
-        }
-    }
-
-    if (level == 0)
-        return EIO;
-
-    /* Compute offsets for the topmost level */
-    uint64_t block_offset_in_level =
-            iblock - fs->inode_block_limits[level - 1];
-    current_block = ext4_inode_get_indirect_block(inode, level - 1);
-    uint32_t offset_in_block =
-            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-
-    /* Sparse file */
-    if (current_block == 0) {
-        *fblock = 0;
-        return EOK;
-    }
-
-    struct	ext4_block block;
-
-    /*
-     * Navigate through other levels, until we find the block number
-     * or find null reference meaning we are dealing with sparse file
-     */
-    while (level > 0) {
-        /* Load indirect block */
-        int rc = ext4_block_get(fs->bdev, &block, current_block);
-        if (rc != EOK)
-            return rc;
-
-        /* Read block address from indirect block */
-        current_block =
-                to_le32(((uint32_t *) block.data)[offset_in_block]);
-
-        /* Put back indirect block untouched */
-        rc = ext4_block_set(fs->bdev, &block);
-        if (rc != EOK)
-            return rc;
-
-        /* Check for sparse file */
-        if (current_block == 0) {
-            *fblock = 0;
-            return EOK;
-        }
-
-        /* Jump to the next level */
-        level--;
-
-        /* Termination condition - we have address of data block loaded */
-        if (level == 0)
-            break;
-
-        /* Visit the next level */
-        block_offset_in_level %= fs->inode_blocks_per_level[level];
-        offset_in_block =
-                block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-    }
-
-    *fblock = current_block;
-
-    return EOK;
-}
-
-int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
-    uint64_t iblock, uint32_t fblock)
-{
-    struct ext4_fs *fs = inode_ref->fs;
-
-    /* Handle inode using extents */
-    if ((ext4_sb_check_feature_incompatible(&fs->sb,
-            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
-            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
-        /* Not reachable */
-        return ENOTSUP;
-    }
-
-    /* Handle simple case when we are dealing with direct reference */
-    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
-        ext4_inode_set_direct_block(inode_ref->inode, (uint32_t) iblock,
-                fblock);
-        inode_ref->dirty = true;
-
-        return EOK;
-    }
-
-    /* Determine the indirection level needed to get the desired block */
-    unsigned int level = 0;
-    unsigned int i;
-    for (i = 1; i < 4; i++) {
-        if (iblock < fs->inode_block_limits[i]) {
-            level = i;
-            break;
-        }
-    }
-
-    if (level == 0)
-        return EIO;
-
-    uint32_t block_size = ext4_sb_get_block_size(&fs->sb);
-
-    /* Compute offsets for the topmost level */
-    uint64_t block_offset_in_level =
-            iblock - fs->inode_block_limits[level - 1];
-    uint32_t current_block =
-            ext4_inode_get_indirect_block(inode_ref->inode, level - 1);
-    uint32_t offset_in_block =
-            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-
-    uint32_t new_block_addr;
-
-    struct	ext4_block block;
-    struct	ext4_block new_block;
-
-    /* Is needed to allocate indirect block on the i-node level */
-    if (current_block == 0) {
-        /* Allocate new indirect block */
-        int rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
-        if (rc != EOK)
-            return rc;
-
-        /* Update i-node */
-        ext4_inode_set_indirect_block(inode_ref->inode, level - 1,
-            new_block_addr);
-        inode_ref->dirty = true;
-
-        /* Load newly allocated block */
-        rc = ext4_block_get(fs->bdev, &new_block, new_block_addr);
-        if (rc != EOK) {
-            ext4_balloc_free_block(inode_ref, new_block_addr);
-            return rc;
-        }
-
-        /* Initialize new block */
-        memset(new_block.data, 0, block_size);
-        new_block.dirty = true;
-
-        /* Put back the allocated block */
-        rc = ext4_block_set(fs->bdev, &new_block);
-        if (rc != EOK)
-            return rc;
-
-        current_block = new_block_addr;
-    }
-
-    /*
-     * Navigate through other levels, until we find the block number
-     * or find null reference meaning we are dealing with sparse file
-     */
-    while (level > 0) {
-        int rc = ext4_block_get(fs->bdev, &block, current_block);
-        if (rc != EOK)
-            return rc;
-
-        current_block =
-                to_le32(((uint32_t *) block.data)[offset_in_block]);
-
-        if ((level > 1) && (current_block == 0)) {
-            /* Allocate new block */
-            rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr);
-            if (rc != EOK) {
-                ext4_block_set(fs->bdev, &block);
-                return rc;
-            }
-
-            /* Load newly allocated block */
-            rc = ext4_block_get(fs->bdev, &new_block, new_block_addr);
-
-            if (rc != EOK) {
-                ext4_block_set(fs->bdev, &block);
-                return rc;
-            }
-
-            /* Initialize allocated block */
-            memset(new_block.data, 0, block_size);
-            new_block.dirty = true;
-
-            rc = ext4_block_set(fs->bdev, &new_block);
-            if (rc != EOK) {
-                ext4_block_set(fs->bdev, &block);
-                return rc;
-            }
-
-            /* Write block address to the parent */
-            ((uint32_t *) block.data)[offset_in_block] =
-                    to_le32(new_block_addr);
-            block.dirty = true;
-            current_block = new_block_addr;
-        }
-
-        /* Will be finished, write the fblock address */
-        if (level == 1) {
-            ((uint32_t *) block.data)[offset_in_block] =
-                    to_le32(fblock);
-            block.dirty = true;
-        }
-
-        rc = ext4_block_set(fs->bdev, &block);
-        if (rc != EOK)
-            return rc;
-
-        level--;
-
-        /*
-         * If we are on the last level, break here as
-         * there is no next level to visit
-         */
-        if (level == 0)
-            break;
-
-        /* Visit the next level */
-        block_offset_in_level %= fs->inode_blocks_per_level[level];
-        offset_in_block =
-                block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-    }
-
-    return EOK;
-}
-
-int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
-    uint32_t iblock)
-{
-    uint32_t fblock;
-
-    struct ext4_fs *fs = inode_ref->fs;
-
-    /* Extents are handled otherwise = there is not support in this function */
-    ext4_assert(!(ext4_sb_check_feature_incompatible(&fs->sb,
-            EXT4_FEATURE_INCOMPAT_EXTENTS) &&
-            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));
-
-    struct ext4_inode *inode = inode_ref->inode;
-
-    /* Handle simple case when we are dealing with direct reference */
-    if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
-        fblock = ext4_inode_get_direct_block(inode, iblock);
-
-        /* Sparse file */
-        if (fblock == 0)
-            return EOK;
-
-        ext4_inode_set_direct_block(inode, iblock, 0);
-        return ext4_balloc_free_block(inode_ref, fblock);
-    }
-
-    /* Determine the indirection level needed to get the desired block */
-    unsigned int level = 0;
-    unsigned int i;
-    for (i = 1; i < 4; i++) {
-        if (iblock < fs->inode_block_limits[i]) {
-            level = i;
-            break;
-        }
-    }
-
-    if (level == 0)
-        return EIO;
-
-    /* Compute offsets for the topmost level */
-    uint64_t block_offset_in_level =
-            iblock - fs->inode_block_limits[level - 1];
-    uint32_t current_block =
-            ext4_inode_get_indirect_block(inode, level - 1);
-    uint32_t offset_in_block =
-            block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-
-    /*
-     * Navigate through other levels, until we find the block number
-     * or find null reference meaning we are dealing with sparse file
-     */
-    struct	ext4_block block;
-
-    while (level > 0) {
-
-        /* Sparse check */
-        if (current_block == 0)
-            return EOK;
-
-        int rc = ext4_block_get(fs->bdev, &block, current_block);
-        if (rc != EOK)
-            return rc;
-
-        current_block =
-                to_le32(((uint32_t *) block.data)[offset_in_block]);
-
-        /* Set zero if physical data block address found */
-        if (level == 1) {
-            ((uint32_t *) block.data)[offset_in_block] =
-                    to_le32(0);
-            block.dirty = true;
-        }
-
-        rc = ext4_block_set(fs->bdev, &block);
-        if (rc != EOK)
-            return rc;
-
-        level--;
-
-        /*
-         * If we are on the last level, break here as
-         * there is no next level to visit
-         */
-        if (level == 0)
-            break;
-
-        /* Visit the next level */
-        block_offset_in_level %= fs->inode_blocks_per_level[level];
-        offset_in_block =
-                block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-    }
-
-    fblock = current_block;
-    if (fblock == 0)
-        return EOK;
-
-    /* Physical block is not referenced, it can be released */
-    return ext4_balloc_free_block(inode_ref, fblock);
-}
-
-
-int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
-    uint32_t *fblock, uint32_t *iblock)
-{
-    /* Handle extents separately */
-    if ((ext4_sb_check_feature_incompatible(&inode_ref->fs->sb,
-            EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
-            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))){
-
-#if 0
-        return ext4_extent_append_block(inode_ref, iblock, fblock, true);
-#endif
-    }
-
-    struct ext4_sblock *sb = &inode_ref->fs->sb;
-
-    /* Compute next block index and allocate data block */
-    uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
-    uint32_t block_size = ext4_sb_get_block_size(sb);
-
-    /* Align size i-node size */
-    if ((inode_size % block_size) != 0)
-        inode_size += block_size - (inode_size % block_size);
-
-    /* Logical blocks are numbered from 0 */
-    uint32_t new_block_idx = inode_size / block_size;
-
-    /* Allocate new physical block */
-    uint32_t phys_block;
-    int rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
-    if (rc != EOK)
-        return rc;
-
-    /* Add physical block address to the i-node */
-    rc = ext4_fs_set_inode_data_block_index(inode_ref,
-            new_block_idx, phys_block);
-    if (rc != EOK) {
-        ext4_balloc_free_block(inode_ref, phys_block);
-        return rc;
-    }
-
-    /* Update i-node */
-    ext4_inode_set_size(inode_ref->inode, inode_size + block_size);
-    inode_ref->dirty = true;
-
-    *fblock = phys_block;
-    *iblock = new_block_idx;
-
-    return EOK;
-}
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_fs.h
+++ /dev/null
@@ -1,95 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_fs.c
- * @brief More complex filesystem functions.
- */
-
-#ifndef EXT4_FS_H_
-#define EXT4_FS_H_
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-
-int ext4_fs_init(struct ext4_fs *fs, struct ext4_blockdev *bdev);
-int ext4_fs_fini(struct ext4_fs *fs);
-
-int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only);
-
-
-uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr);
-uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
-    uint32_t bgid);
-
-
-int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
-    struct ext4_block_group_ref *ref);
-int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref);
-
-
-int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
-    struct ext4_inode_ref *ref);
-int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref);
-
-
-int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
-    bool is_directory);
-int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref);
-
-int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref,
-        uint64_t new_size);
-
-int ext4_fs_get_inode_data_block_index(struct ext4_inode_ref *inode_ref,
-        uint64_t iblock, uint32_t *fblock);
-
-int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
-        uint64_t iblock, uint32_t fblock);
-
-int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
-        uint32_t iblock);
-
-int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
-        uint32_t *fblock, uint32_t *iblock);
-
-#endif /* EXT4_FS_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_hash.c
+++ /dev/null
@@ -1,320 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- * FreeBSD:
- * Copyright (c) 2010, 2013 Zheng Liu <lz@freebsd.org>
- * Copyright (c) 2012, Vyacheslav Matyushin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- */
-
-/*
- * The following notice applies to the code in ext2_half_md4():
- *
- * Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
- *
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- *
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD4 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- *
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software for any particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- *
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
- */
-
-/** @addtogroup lwext4
- * @{
- */
-/**
- * @file  ext4_hash.c
- * @brief Directory indexing hash functions.
- */
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-#include <string.h>
-#include <ext4_errno.h>
-
-/* F, G, and H are MD4 functions */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-
-/* ROTATE_LEFT rotates x left n bits */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
-/*
- * FF, GG, and HH are transformations for rounds 1, 2, and 3.
- * Rotation is separated from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s) { \
-        (a) += F ((b), (c), (d)) + (x); \
-        (a) = ROTATE_LEFT ((a), (s)); \
-}
-
-#define GG(a, b, c, d, x, s) { \
-        (a) += G ((b), (c), (d)) + (x) + (uint32_t)0x5A827999; \
-        (a) = ROTATE_LEFT ((a), (s)); \
-}
-
-#define HH(a, b, c, d, x, s) { \
-        (a) += H ((b), (c), (d)) + (x) + (uint32_t)0x6ED9EBA1; \
-        (a) = ROTATE_LEFT ((a), (s)); \
-}
-
-/*
- * MD4 basic transformation.  It transforms state based on block.
- *
- * This is a half md4 algorithm since Linux uses this algorithm for dir
- * index.  This function is derived from the RSA Data Security, Inc. MD4
- * Message-Digest Algorithm and was modified as necessary.
- *
- * The return value of this function is uint32_t in Linux, but actually we don't
- * need to check this value, so in our version this function doesn't return any
- * value.
- */
-static void
-ext2_half_md4(uint32_t hash[4], uint32_t data[8])
-{
-    uint32_t a = hash[0], b = hash[1], c = hash[2], d = hash[3];
-
-    /* Round 1 */
-    FF(a, b, c, d, data[0],  3);
-    FF(d, a, b, c, data[1],  7);
-    FF(c, d, a, b, data[2], 11);
-    FF(b, c, d, a, data[3], 19);
-    FF(a, b, c, d, data[4],  3);
-    FF(d, a, b, c, data[5],  7);
-    FF(c, d, a, b, data[6], 11);
-    FF(b, c, d, a, data[7], 19);
-
-    /* Round 2 */
-    GG(a, b, c, d, data[1],  3);
-    GG(d, a, b, c, data[3],  5);
-    GG(c, d, a, b, data[5],  9);
-    GG(b, c, d, a, data[7], 13);
-    GG(a, b, c, d, data[0],  3);
-    GG(d, a, b, c, data[2],  5);
-    GG(c, d, a, b, data[4],  9);
-    GG(b, c, d, a, data[6], 13);
-
-    /* Round 3 */
-    HH(a, b, c, d, data[3],  3);
-    HH(d, a, b, c, data[7],  9);
-    HH(c, d, a, b, data[2], 11);
-    HH(b, c, d, a, data[6], 15);
-    HH(a, b, c, d, data[1],  3);
-    HH(d, a, b, c, data[5],  9);
-    HH(c, d, a, b, data[0], 11);
-    HH(b, c, d, a, data[4], 15);
-
-    hash[0] += a;
-    hash[1] += b;
-    hash[2] += c;
-    hash[3] += d;
-}
-
-/*
- * Tiny Encryption Algorithm.
- */
-static void
-ext2_tea(uint32_t hash[4], uint32_t data[8])
-{
-    uint32_t tea_delta = 0x9E3779B9;
-    uint32_t sum;
-    uint32_t x = hash[0], y = hash[1];
-    int n = 16;
-    int i = 1;
-
-    while (n-- > 0) {
-        sum = i * tea_delta;
-        x += ((y << 4) + data[0]) ^ (y + sum) ^ ((y >> 5) + data[1]);
-        y += ((x << 4) + data[2]) ^ (x + sum) ^ ((x >> 5) + data[3]);
-        i++;
-    }
-
-    hash[0] += x;
-    hash[1] += y;
-}
-
-static uint32_t
-ext2_legacy_hash(const char *name, int len, int unsigned_char)
-{
-    uint32_t h0, h1 = 0x12A3FE2D, h2 = 0x37ABE8F9;
-    uint32_t multi = 0x6D22F5;
-    const unsigned char *uname = (const unsigned char *)name;
-    const signed char *sname = (const signed char *)name;
-    int val, i;
-
-    for (i = 0; i < len; i++) {
-        if (unsigned_char)
-            val = (unsigned int)*uname++;
-        else
-            val = (int)*sname++;
-
-        h0 = h2 + (h1 ^ (val * multi));
-        if (h0 & 0x80000000)
-            h0 -= 0x7FFFFFFF;
-        h2 = h1;
-        h1 = h0;
-    }
-
-    return (h1 << 1);
-}
-
-static void
-ext2_prep_hashbuf(const char *src, int slen, uint32_t *dst, int dlen,
-        int unsigned_char)
-{
-    uint32_t padding = slen | (slen << 8) | (slen << 16) | (slen << 24);
-    uint32_t buf_val;
-    int len, i;
-    int buf_byte;
-    const unsigned char *ubuf = (const unsigned char *)src;
-    const signed char *sbuf = (const signed char *)src;
-
-    if (slen > dlen)
-        len = dlen;
-    else
-        len = slen;
-
-    buf_val = padding;
-
-    for (i = 0; i < len; i++) {
-        if (unsigned_char)
-            buf_byte = (unsigned int)ubuf[i];
-        else
-            buf_byte = (int)sbuf[i];
-
-        if ((i % 4) == 0)
-            buf_val = padding;
-
-        buf_val <<= 8;
-        buf_val += buf_byte;
-
-        if ((i % 4) == 3) {
-            *dst++ = buf_val;
-            dlen -= sizeof(uint32_t);
-            buf_val = padding;
-        }
-    }
-
-    dlen -= sizeof(uint32_t);
-    if (dlen >= 0)
-        *dst++ = buf_val;
-
-    dlen -= sizeof(uint32_t);
-    while (dlen >= 0) {
-        *dst++ = padding;
-        dlen -= sizeof(uint32_t);
-    }
-}
-
-int
-ext2_htree_hash(const char *name, int len,
-        const uint32_t *hash_seed, int hash_version,
-        uint32_t *hash_major, uint32_t *hash_minor)
-{
-    uint32_t hash[4];
-    uint32_t data[8];
-    uint32_t major = 0, minor = 0;
-    int unsigned_char = 0;
-
-    if (!name || !hash_major)
-        return (-1);
-
-    if (len < 1 || len > 255)
-        goto error;
-
-    hash[0] = 0x67452301;
-    hash[1] = 0xEFCDAB89;
-    hash[2] = 0x98BADCFE;
-    hash[3] = 0x10325476;
-
-    if (hash_seed)
-        memcpy(hash, hash_seed, sizeof(hash));
-
-    switch (hash_version) {
-    case EXT2_HTREE_TEA_UNSIGNED:
-        unsigned_char = 1;
-    case EXT2_HTREE_TEA:
-        while (len > 0) {
-            ext2_prep_hashbuf(name, len, data, 16, unsigned_char);
-            ext2_tea(hash, data);
-            len -= 16;
-            name += 16;
-        }
-        major = hash[0];
-        minor = hash[1];
-        break;
-    case EXT2_HTREE_LEGACY_UNSIGNED:
-        unsigned_char = 1;
-    case EXT2_HTREE_LEGACY:
-        major = ext2_legacy_hash(name, len, unsigned_char);
-        break;
-    case EXT2_HTREE_HALF_MD4_UNSIGNED:
-        unsigned_char = 1;
-    case EXT2_HTREE_HALF_MD4:
-        while (len > 0) {
-            ext2_prep_hashbuf(name, len, data, 32, unsigned_char);
-            ext2_half_md4(hash, data);
-            len -= 32;
-            name += 32;
-        }
-        major = hash[0];
-        minor = hash[1];
-        break;
-    default:
-        goto error;
-    }
-
-    major &= ~1;
-    if (major == (EXT2_HTREE_EOF << 1))
-        major = (EXT2_HTREE_EOF - 1) << 1;
-    *hash_major = major;
-    if (hash_minor)
-        *hash_minor = minor;
-
-    return EOK;
-
-    error:
-    *hash_major = 0;
-    if (hash_minor)
-        *hash_minor = 0;
-    return ENOTSUP;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_hash.h
+++ /dev/null
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- * 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 lwext4
- * @{
- */
-/**
- * @file  ext4_hash.h
- * @brief Directory indexing hash functions.
- */
-
-#ifndef EXT4_HASH_H_
-#define EXT4_HASH_H_
-
-#include <ext4_config.h>
-
-#include <stdint.h>
-
-/**@brief	Directory entry name hash function.
- * @param	name entry name
- * @param	len entry name length
- * @param	hash_seed (from superblock)
- * @param	hash version (from superblock)
- * @param	hash_minor output value
- * @param	hash_major output value
- * @return 	standard error code*/
-int ext2_htree_hash(const char *name, int len,
-        const uint32_t *hash_seed, int hash_version,
-        uint32_t *hash_major, uint32_t *hash_minor);
-
-
-#endif /* EXT4_HASH_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_ialloc.c
+++ /dev/null
@@ -1,250 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_ialloc.c
- * @brief Inode allocation procedures.
- */
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-#include <ext4_ialloc.h>
-#include <ext4_super.h>
-#include <ext4_fs.h>
-#include <ext4_blockdev.h>
-#include <ext4_block_group.h>
-#include <ext4_bitmap.h>
-
-static uint32_t ext4_ialloc_inode2index_in_group(struct ext4_sblock *sb,
-    uint32_t inode)
-{
-    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
-    return (inode - 1) % inodes_per_group;
-}
-
-static uint32_t ext4_ialloc_index_in_group2inode(struct ext4_sblock *sb,
-        uint32_t index, uint32_t bgid)
-{
-    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
-    return bgid * inodes_per_group + (index + 1);
-}
-
-static uint32_t ext4_ialloc_get_bgid_of_inode(struct ext4_sblock *sb,
-        uint32_t inode)
-{
-    uint32_t inodes_per_group = ext4_get32(sb, inodes_per_group);
-    return (inode - 1) / inodes_per_group;
-}
-
-
-int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir)
-{
-    struct ext4_sblock *sb = &fs->sb;
-
-    /* Compute index of block group and load it */
-    uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index);
-
-    struct ext4_block_group_ref bg_ref;
-    int rc = ext4_fs_get_block_group_ref(fs, block_group, &bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    /* Load i-node bitmap */
-    uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(
-            bg_ref.block_group, sb);
-
-    struct	ext4_block bitmap_block;
-    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
-    if (rc != EOK)
-        return rc;
-
-    /* Free i-node in the bitmap */
-    uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index);
-    ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
-    bitmap_block.dirty = true;
-
-    /* Put back the block with bitmap */
-    rc = ext4_block_set(fs->bdev, &bitmap_block);
-    if (rc != EOK) {
-        /* Error in saving bitmap */
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
-
-    /* If released i-node is a directory, decrement used directories count */
-    if (is_dir) {
-        uint32_t bg_used_dirs = ext4_bg_get_used_dirs_count(
-                bg_ref.block_group, sb);
-        bg_used_dirs--;
-        ext4_bg_set_used_dirs_count(bg_ref.block_group, sb,
-                bg_used_dirs);
-    }
-
-    /* Update block group free inodes count */
-    uint32_t free_inodes = ext4_bg_get_free_inodes_count(
-            bg_ref.block_group, sb);
-    free_inodes++;
-    ext4_bg_set_free_inodes_count(bg_ref.block_group, sb,
-            free_inodes);
-
-    bg_ref.dirty = true;
-
-    /* Put back the modified block group */
-    rc = ext4_fs_put_block_group_ref(&bg_ref);
-    if (rc != EOK)
-        return rc;
-
-    /* Update superblock free inodes count */
-    ext4_set32(sb, free_inodes_count, ext4_get32(sb, free_inodes_count) + 1);
-
-    return EOK;
-}
-
-int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir)
-{
-    struct ext4_sblock *sb = &fs->sb;
-
-    uint32_t bgid = 0;
-    uint32_t bg_count = ext4_block_group_cnt(sb);
-    uint32_t sb_free_inodes = ext4_get32(sb, free_inodes_count);
-    uint32_t avg_free_inodes = sb_free_inodes / bg_count;
-
-    /* Try to find free i-node in all block groups */
-    while (bgid < bg_count) {
-        /* Load block group to check */
-        struct ext4_block_group_ref bg_ref;
-        int rc = ext4_fs_get_block_group_ref(fs, bgid, &bg_ref);
-        if (rc != EOK)
-            return rc;
-
-        struct ext4_bgroup *bg = bg_ref.block_group;
-
-        /* Read necessary values for algorithm */
-        uint32_t free_blocks = ext4_bg_get_free_blocks_count(bg, sb);
-        uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);
-        uint32_t used_dirs = ext4_bg_get_used_dirs_count(bg, sb);
-
-        /* Check if this block group is good candidate for allocation */
-        if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) {
-            /* Load block with bitmap */
-            uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(
-                    bg_ref.block_group, sb);
-
-            struct	ext4_block bitmap_block;
-            rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
-            if (rc != EOK)
-                return rc;
-
-            /* Try to allocate i-node in the bitmap */
-            uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bgid);
-            uint32_t index_in_group;
-
-            rc = ext4_bmap_bit_find_clr(bitmap_block.data, 0, inodes_in_group,
-                    &index_in_group);
-            /* Block group has not any free i-node */
-            if (rc == ENOSPC) {
-                ext4_block_set(fs->bdev, &bitmap_block);
-                ext4_fs_put_block_group_ref(&bg_ref);
-                continue;
-            }
-
-            ext4_bmap_bit_set(bitmap_block.data, index_in_group);
-
-            /* Free i-node found, save the bitmap */
-            bitmap_block.dirty = true;
-
-            ext4_block_set(fs->bdev, &bitmap_block);
-            if (rc != EOK)
-                return rc;
-
-            /* Modify filesystem counters */
-            free_inodes--;
-            ext4_bg_set_free_inodes_count(bg, sb, free_inodes);
-
-            /* Increment used directories counter */
-            if (is_dir) {
-                used_dirs++;
-                ext4_bg_set_used_dirs_count(bg, sb, used_dirs);
-            }
-
-            /* Decrease unused inodes count */
-            if (ext4_bg_has_flag(bg,
-                    EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
-                uint32_t unused =
-                        ext4_bg_get_itable_unused(bg, sb);
-
-                uint32_t inodes_in_group =
-                        ext4_inodes_in_group_cnt(sb, bgid);
-
-                uint32_t free = inodes_in_group - unused;
-
-                if (index_in_group >= free) {
-                    unused = inodes_in_group - (index_in_group + 1);
-                    ext4_bg_set_itable_unused(bg, sb, unused);
-                }
-            }
-
-            /* Save modified block group */
-            bg_ref.dirty = true;
-
-            rc = ext4_fs_put_block_group_ref(&bg_ref);
-            if (rc != EOK)
-                return rc;
-
-            /* Update superblock */
-            sb_free_inodes--;
-            ext4_set32(sb, free_inodes_count, sb_free_inodes);
-
-
-            /* Compute the absolute i-nodex number */
-            *index = ext4_ialloc_index_in_group2inode(sb,
-                    index_in_group, bgid);
-
-            return EOK;
-        }
-
-        /* Block group not modified, put it and jump to the next block group */
-        ext4_fs_put_block_group_ref(&bg_ref);
-        ++bgid;
-    }
-
-    return ENOSPC;
-}
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_ialloc.h
+++ /dev/null
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_ialloc.c
- * @brief Inode allocation procedures.
- */
-
-#ifndef EXT4_IALLOC_H_
-#define EXT4_IALLOC_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-
-
-int ext4_ialloc_free_inode(struct ext4_fs *fs, uint32_t index, bool is_dir);
-int ext4_ialloc_alloc_inode(struct ext4_fs *fs, uint32_t *index, bool is_dir);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* EXT4_IALLOC_H_ */
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_inode.c
+++ /dev/null
@@ -1,353 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_inode.c
- * @brief Inode handle functions
- */
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-#include <ext4_inode.h>
-#include <ext4_super.h>
-
-static uint32_t ext4_inode_block_bits_count(uint32_t block_size)
-{
-    uint32_t bits = 8;
-    uint32_t size = block_size;
-
-    do {
-        bits++;
-        size = size >> 1;
-    } while (size > 256);
-
-    return bits;
-}
-
-
-uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode)
-{
-    uint32_t v = to_le16(inode->mode);
-
-    if(ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD){
-        v |= ((uint32_t) to_le16(inode->osd2.hurd2.mode_high)) << 16;
-    }
-
-    return v;
-}
-
-void 	 ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
-    uint32_t mode)
-{
-    inode->mode = to_le16((mode << 16) >> 16);
-
-    if(ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)
-        inode->osd2.hurd2.mode_high = to_le16(mode >> 16);
-}
-
-
-
-uint32_t ext4_inode_get_uid(struct ext4_inode *inode)
-{
-    return to_le32(inode->uid);
-}
-
-void 	 ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid)
-{
-    inode->uid = to_le32(uid);
-}
-
-
-uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode)
-{
-    uint64_t v = to_le32(inode->size_lo);
-
-    if ((ext4_get32(sb, rev_level) > 0) && (ext4_inode_is_type(sb, inode,
-            EXT4_INODE_MODE_FILE)))
-        v |= ((uint64_t)to_le32(inode->size_hi)) << 32;
-
-    return v;
-}
-
-void 	 ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)
-{
-    inode->size_lo = to_le32((size << 32) >> 32);
-    inode->size_hi = to_le32(size >> 32);
-}
-
-
-uint32_t ext4_inode_get_access_time(struct ext4_inode *inode)
-{
-    return to_le32(inode->access_time);
-}
-void 	 ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time)
-{
-    inode->access_time = to_le32(time);
-}
-
-
-uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode)
-{
-    return to_le32(inode->change_inode_time);
-}
-void 	 ext4_inode_set_change_inode_time(struct ext4_inode *inode,
-    uint32_t time)
-{
-    inode->change_inode_time = to_le32(time);
-}
-
-
-uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode)
-{
-    return to_le32(inode->modification_time);
-}
-
-void 	 ext4_inode_set_modification_time(struct ext4_inode *inode,
-    uint32_t time)
-{
-    inode->modification_time = to_le32(time);
-}
-
-
-uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode)
-{
-    return to_le32(inode->deletion_time);
-}
-
-void 	 ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time)
-{
-    inode->deletion_time = to_le32(time);
-}
-
-uint32_t ext4_inode_get_gid(struct ext4_inode *inode)
-{
-    return to_le32(inode->gid);
-}
-void 	 ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid)
-{
-    inode->gid	= to_le32(gid);
-}
-
-uint16_t ext4_inode_get_links_count(struct ext4_inode *inode)
-{
-    return to_le16(inode->links_count);
-}
-void 	 ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt)
-{
-    inode->links_count = to_le16(cnt);
-}
-
-
-uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
-    struct ext4_inode *inode)
-{
-    uint64_t count = to_le32(inode->blocks_count_lo);
-
-    if (ext4_sb_check_read_only(sb,
-            EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
-
-        /* 48-bit field */
-        count = ((uint64_t) to_le16(inode->osd2.linux2.blocks_high)) << 32;
-
-        if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {
-
-            uint32_t block_bits =
-                    ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
-            return count << (block_bits - 9);
-        } else
-            return count;
-    }
-
-    return count;
-}
-
-
-int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
-    struct ext4_inode *inode, uint64_t count)
-{
-    /* 32-bit maximum */
-    uint64_t max = 0;
-    max = ~max >> 32;
-
-    if (count <= max) {
-        inode->blocks_count_lo = to_le32(count);
-        inode->osd2.linux2.blocks_high = 0;
-        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
-
-        return EOK;
-    }
-
-    /* Check if there can be used huge files (many blocks) */
-    if (!ext4_sb_check_read_only(sb,
-            EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
-        return EINVAL;
-
-    /* 48-bit maximum */
-    max = 0;
-    max = ~max >> 16;
-
-    if (count <= max) {
-        inode->blocks_count_lo = to_le32(count);
-        inode->osd2.linux2.blocks_high = to_le16(count >> 32);
-        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
-    } else {
-        uint32_t block_bits = ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));
-
-        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
-        count = count >> (block_bits - 9);
-        inode->blocks_count_lo = to_le32(count);
-        inode->osd2.linux2.blocks_high = to_le16(count >> 32);
-    }
-
-    return EOK;
-}
-
-
-uint32_t ext4_inode_get_flags(struct ext4_inode *inode)
-{
-    return to_le32(inode->flags);
-}
-void 	 ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags)
-{
-    inode->flags = 	to_le32(flags);
-}
-
-uint32_t ext4_inode_get_generation(struct ext4_inode *inode)
-{
-    return to_le32(inode->generation);
-}
-void 	 ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen)
-{
-    inode->generation = to_le32(gen);
-}
-
-uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
-    struct ext4_sblock *sb)
-{
-    /*TODO: Verify it*/
-    uint64_t v = to_le32(inode->file_acl_lo);
-
-    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
-        v |= ((uint32_t) to_le16(inode->osd2.linux2.file_acl_high)) << 16;
-
-
-    return v;
-}
-
-void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,
-    uint64_t acl)
-{
-    /*TODO: Verify it*/
-    inode->file_acl_lo = to_le32((acl << 32) >> 32);
-
-    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
-        inode->osd2.linux2.file_acl_high = to_le16(acl >> 32);
-}
-
-
-
-uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx)
-{
-    return to_le32(inode->blocks[idx]);
-}
-void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
-    uint32_t block)
-{
-    inode->blocks[idx] = to_le32(block);
-}
-
-
-uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx)
-{
-    return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);
-}
-
-void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
-    uint32_t block)
-{
-    inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);
-}
-
-bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
-    uint32_t type)
-{
-    return (ext4_inode_get_mode(sb, inode) &
-            EXT4_INODE_MODE_TYPE_MASK) == type;
-}
-
-bool 	 ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f)
-{
-    return ext4_inode_get_flags(inode) & f;
-}
-
-void 	 ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f)
-{
-    uint32_t flags = ext4_inode_get_flags(inode);
-    flags = flags & (~f);
-    ext4_inode_set_flags(inode, flags);
-}
-
-void 	 ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f)
-{
-    uint32_t flags = ext4_inode_get_flags(inode);
-    flags = flags | f;
-    ext4_inode_set_flags(inode, flags);
-}
-
-bool 	 ext4_inode_can_truncate(struct ext4_sblock *sb,
-    struct ext4_inode *inode)
-{
-    if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||
-            (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))
-        return false;
-
-    if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||
-            (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)))
-        return true;
-
-    return false;
-}
-
-
-struct ext4_extent_header * ext4_inode_get_extent_header(
-    struct ext4_inode *inode)
-{
-    return (struct ext4_extent_header *) inode->blocks;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_inode.h
+++ /dev/null
@@ -1,129 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_inode.h
- * @brief Inode handle functions
- */
-
-#ifndef EXT4_INODE_H_
-#define EXT4_INODE_H_
-
-#include <ext4_config.h>
-#include <stdint.h>
-
-uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode);
-void ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
-    uint32_t mode);
-
-
-uint32_t ext4_inode_get_uid(struct ext4_inode *inode);
-void 	 ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid);
-
-
-uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode);
-void ext4_inode_set_size(struct ext4_inode *inode, uint64_t size);
-
-
-uint32_t ext4_inode_get_access_time(struct ext4_inode *inode);
-void 	 ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time);
-
-
-uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode);
-void ext4_inode_set_change_inode_time(struct ext4_inode *inode,
-    uint32_t time);
-
-
-uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode);
-void ext4_inode_set_modification_time(struct ext4_inode *inode, uint32_t time);
-
-
-uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode);
-void ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time);
-
-uint32_t ext4_inode_get_gid(struct ext4_inode *inode);
-void 	 ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid);
-
-uint16_t ext4_inode_get_links_count(struct ext4_inode *inode);
-void ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt);
-
-
-uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
-    struct ext4_inode *inode);
-int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
-    struct ext4_inode *inode, uint64_t cnt);
-
-
-uint32_t ext4_inode_get_flags(struct ext4_inode *inode);
-void ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags);
-
-uint32_t ext4_inode_get_generation(struct ext4_inode *inode);
-void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen);
-
-uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
-    struct ext4_sblock *sb);
-void ext4_inode_set_file_acl(struct ext4_inode *inode,
-    struct ext4_sblock *sb, uint64_t acl);
-
-
-uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx);
-void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
-    uint32_t block);
-
-
-uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx);
-void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
-    uint32_t block);
-
-bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
-    uint32_t type);
-
-
-bool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f);
-void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f);
-void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f);
-
-bool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode);
-
-
-struct ext4_extent_header * ext4_inode_get_extent_header(struct ext4_inode *inode);
-
-#endif /* EXT4_INODE_H_ */
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_super.c
+++ /dev/null
@@ -1,133 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_super.h
- * @brief Superblock operations.
- */
-
-#include <ext4_config.h>
-#include <ext4_super.h>
-
-
-uint32_t ext4_block_group_cnt(struct ext4_sblock *s)
-{
-    uint64_t blocks_count = ext4_sb_get_blocks_cnt(s);
-    uint32_t blocks_per_group = ext4_get32(s, blocks_per_group);
-
-    uint32_t block_groups_count = blocks_count / blocks_per_group;
-
-    if (blocks_count % blocks_per_group)
-        block_groups_count++;
-
-    return block_groups_count;
-}
-
-uint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid)
-{
-    uint32_t block_group_count = ext4_block_group_cnt(s);
-    uint32_t blocks_per_group  = ext4_get32(s, blocks_per_group);
-    uint64_t total_blocks 	   = ext4_sb_get_blocks_cnt(s);
-
-    if (bgid < block_group_count - 1)
-        return blocks_per_group;
-
-
-    return (total_blocks - ((block_group_count - 1) * blocks_per_group));
-}
-
-uint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid)
-{
-    uint32_t block_group_count = ext4_block_group_cnt(s);
-    uint32_t inodes_per_group  = ext4_get32(s, inodes_per_group);
-    uint32_t total_inodes =		 ext4_get32(s, inodes_count);
-
-
-    if (bgid < block_group_count - 1)
-        return inodes_per_group;
-
-    return (total_inodes - ((block_group_count - 1) * inodes_per_group));
-}
-
-int	ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s)
-{
-    return ext4_block_writebytes(bdev, EXT4_SUPERBLOCK_OFFSET,
-            s, EXT4_SUPERBLOCK_SIZE);
-}
-
-int	ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s)
-{
-    return ext4_block_readbytes(bdev, EXT4_SUPERBLOCK_OFFSET,
-            s, EXT4_SUPERBLOCK_SIZE);
-}
-
-bool ext4_sb_check(struct ext4_sblock *s)
-{
-    if (ext4_get16(s, magic) != EXT4_SUPERBLOCK_MAGIC)
-        return false;
-
-    if (ext4_get32(s, inodes_count) == 0)
-        return false;
-
-    if (ext4_sb_get_blocks_cnt(s) == 0)
-        return false;
-
-    if (ext4_get32(s, blocks_per_group) == 0)
-        return false;
-
-    if (ext4_get32(s, inodes_per_group) == 0)
-        return false;
-
-    if (ext4_get16(s, inode_size) < 128)
-        return false;
-
-    if (ext4_get32(s, first_inode) < 11)
-        return false;
-
-    if (ext4_sb_get_desc_size(s) <
-            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        return false;
-
-    if (ext4_sb_get_desc_size(s)  >
-    EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE)
-        return false;
-
-    return true;
-}
-
-/**
- * @}
- */
--- a/src/lwext4/ext4_super.h
+++ /dev/null
@@ -1,187 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_super.c
- * @brief Superblock operations.
- */
-
-#ifndef EXT4_SUPER_H_
-#define EXT4_SUPER_H_
-
-
-#include <ext4_config.h>
-#include <ext4_types.h>
-
-
-/****************************Unstandard access to superblock*****************/
-
-/**@brief	Blocks count get stored in superblock.
- * @param	s superblock descriptor
- * @return	count of blocks*/
-static inline uint64_t 	ext4_sb_get_blocks_cnt(struct ext4_sblock *s)
-{
-    return ((uint64_t) to_le32(s->blocks_count_hi) << 32) |
-            to_le32(s->blocks_count_lo);
-}
-
-/**@brief	Free blocks count get stored in superblock.
- * @param	s superblock descriptor
- * @return	free blocks*/
-static inline uint64_t 	ext4_sb_get_free_blocks_cnt(struct ext4_sblock *s)
-{
-    return ((uint64_t) to_le32(s->free_blocks_count_hi) << 32) |
-            to_le32(s->free_blocks_count_lo);
-}
-
-/**@brief	Free blocks count set.
- * @param	s superblock descriptor
- * @param	cnt new value of free blocks*/
-static inline void 	ext4_sb_set_free_blocks_cnt(struct ext4_sblock *s,
-    uint64_t cnt)
-{
-    s->free_blocks_count_lo = to_le32((cnt << 32) >> 32);
-    s->free_blocks_count_hi = to_le32(cnt >> 32);
-}
-
-/**@brief	Block size get from superblock.
- * @param	s superblock descriptor
- * @return	block size in bytes*/
-static inline uint32_t 	ext4_sb_get_block_size(struct ext4_sblock *s)
-{
-    return 1024 << to_le32(s->log_block_size);
-}
-
-/**@brief	Block group descriptor size.
- * @param	s superblock descriptor
- * @return	block group descriptor size in bytes*/
-static inline uint16_t ext4_sb_get_desc_size(struct ext4_sblock *s)
-{
-    uint16_t size = to_le16(s->desc_size);
-
-    return size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE ?
-            EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE : size;
-}
-
-/*************************Flags and features*********************************/
-
-/**@brief	Support check of flag.
- * @param	s superblock descriptor
- * @param	v flag to check
- * @return	true if flag is supported*/
-static inline bool ext4_sb_check_flag(struct ext4_sblock *s, uint32_t v)
-{
-    return to_le32(s->flags) & v;
-}
-
-/**@brief	Support check of feature compatible.
- * @param	s superblock descriptor
- * @param	v feature to check
- * @return	true if feature is supported*/
-static inline bool ext4_sb_check_feature_compatible(struct ext4_sblock *s,
-    uint32_t v)
-{
-    return to_le32(s->features_compatible) & v;
-}
-
-
-/**@brief	Support check of feature incompatible.
- * @param	s superblock descriptor
- * @param	v feature to check
- * @return	true if feature is supported*/
-static inline bool ext4_sb_check_feature_incompatible(struct ext4_sblock *s,
-    uint32_t v)
-{
-    return to_le32(s->features_incompatible) & v;
-}
-
-
-/**@brief	Support check of read only flag.
- * @param	s superblock descriptor
- * @param	v flag to check
- * @return	true if flag is supported*/
-static inline bool ext4_sb_check_read_only(struct ext4_sblock *s, uint32_t v)
-{
-    return to_le32(s->features_read_only) & v;
-}
-
-/**************************More complex functions****************************/
-
-/**@brief	Returns a block group count.
- * @param	s superblock descriptor
- * @return	count of block groups*/
-uint32_t ext4_block_group_cnt(struct ext4_sblock *s);
-
-/**@brief	Returns block count in block group
- *          (last block group may have less blocks)
- * @param	s superblock descriptor
- * @param	bgid block group id
- * @return	blocks count*/
-uint32_t ext4_blocks_in_group_cnt(struct ext4_sblock *s, uint32_t bgid);
-
-/**@brief	Returns inodes count in block group
- *          (last block group may have less inodes)
- * @param	s superblock descriptor
- * @param	bgid block group id
- * @return	inodes count*/
-uint32_t ext4_inodes_in_group_cnt(struct ext4_sblock *s, uint32_t bgid);
-
-/***************************Read/write/check superblock**********************/
-
-/**@brief	Superblock write.
- * @param	bdev block device descriptor.
- * @param	s superblock descruptor
- * @return 	Standard error code */
-int	ext4_sb_write(struct ext4_blockdev *bdev, struct ext4_sblock *s);
-
-/**@brief	Superblock read.
- * @param	bdev block device descriptor.
- * @param	s superblock descruptor
- * @return 	Standard error code */
-int	ext4_sb_read(struct ext4_blockdev *bdev, struct ext4_sblock *s);
-
-/**@brief	Superblock simple validation.
- * @param	s superblock dsecriptor
- * @return	true if OK*/
-bool ext4_sb_check(struct ext4_sblock *s);
-
-
-#endif /* EXT4_SUPER_H_ */
-
-/**
- * @}
- */
-
--- a/src/lwext4/ext4_types.h
+++ /dev/null
@@ -1,613 +1,0 @@
-/*
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
- *
- *
- * HelenOS:
- * Copyright (c) 2012 Martin Sucha
- * Copyright (c) 2012 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 lwext4
- * @{
- */
-/**
- * @file  ext4_types.h
- * @brief Ext4 data structure definitions.
- */
-
-#ifndef EXT4_TYPES_H_
-#define EXT4_TYPES_H_
-
-#include <ext4_config.h>
-#include <ext4_blockdev.h>
-
-#include <stdint.h>
-
-
-/*
- * Structure of the super block
- */
-struct ext4_sblock {
-    uint32_t inodes_count;              /* I-nodes count */
-    uint32_t blocks_count_lo;           /* Blocks count */
-    uint32_t reserved_blocks_count_lo;  /* Reserved blocks count */
-    uint32_t free_blocks_count_lo;      /* Free blocks count */
-    uint32_t free_inodes_count;         /* Free inodes count */
-    uint32_t first_data_block;          /* First Data Block */
-    uint32_t log_block_size;            /* Block size */
-    uint32_t log_frag_size;             /* Obsoleted fragment size */
-    uint32_t blocks_per_group;          /* Number of blocks per group */
-    uint32_t frags_per_group;           /* Obsoleted fragments per group */
-    uint32_t inodes_per_group;          /* Number of inodes per group */
-    uint32_t mount_time;                /* Mount time */
-    uint32_t write_time;                /* Write time */
-    uint16_t mount_count;               /* Mount count */
-    uint16_t max_mount_count;           /* Maximal mount count */
-    uint16_t magic;                     /* Magic signature */
-    uint16_t state;                     /* File system state */
-    uint16_t errors;                    /* Behaviour when detecting errors */
-    uint16_t minor_rev_level;           /* Minor revision level */
-    uint32_t last_check_time;           /* Time of last check */
-    uint32_t check_interval;            /* Maximum time between checks */
-    uint32_t creator_os;                /* Creator OS */
-    uint32_t rev_level;                 /* Revision level */
-    uint16_t def_resuid;                /* Default uid for reserved blocks */
-    uint16_t def_resgid;                /* Default gid for reserved blocks */
-
-    /* Fields for EXT4_DYNAMIC_REV superblocks only. */
-    uint32_t first_inode;             /* First non-reserved inode */
-    uint16_t inode_size;              /* Size of inode structure */
-    uint16_t block_group_index;       /* Block group index of this superblock */
-    uint32_t features_compatible;     /* Compatible feature set */
-    uint32_t features_incompatible;   /* Incompatible feature set */
-    uint32_t features_read_only;      /* Readonly-compatible feature set */
-    uint8_t uuid[16];                 /* 128-bit uuid for volume */
-    char volume_name[16];             /* Volume name */
-    char last_mounted[64];            /* Directory where last mounted */
-    uint32_t algorithm_usage_bitmap;  /* For compression */
-
-    /*
-     * Performance hints. Directory preallocation should only
-     * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
-     */
-    uint8_t s_prealloc_blocks;       /* Number of blocks to try to preallocate */
-    uint8_t s_prealloc_dir_blocks;   /* Number to preallocate for dirs */
-    uint16_t s_reserved_gdt_blocks;  /* Per group desc for online growth */
-
-    /*
-     * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
-     */
-    uint8_t journal_uuid[16];       /* UUID of journal superblock */
-    uint32_t journal_inode_number;  /* Inode number of journal file */
-    uint32_t journal_dev;           /* Device number of journal file */
-    uint32_t last_orphan;           /* Head of list of inodes to delete */
-    uint32_t hash_seed[4];          /* HTREE hash seed */
-    uint8_t default_hash_version;   /* Default hash version to use */
-    uint8_t journal_backup_type;
-    uint16_t desc_size;             /* Size of group descriptor */
-    uint32_t default_mount_opts;    /* Default mount options */
-    uint32_t first_meta_bg;         /* First metablock block group */
-    uint32_t mkfs_time;             /* When the filesystem was created */
-    uint32_t journal_blocks[17];    /* Backup of the journal inode */
-
-    /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
-    uint32_t blocks_count_hi;           /* Blocks count */
-    uint32_t reserved_blocks_count_hi;  /* Reserved blocks count */
-    uint32_t free_blocks_count_hi;      /* Free blocks count */
-    uint16_t min_extra_isize;           /* All inodes have at least # bytes */
-    uint16_t want_extra_isize;          /* New inodes should reserve # bytes */
-    uint32_t flags;                     /* Miscellaneous flags */
-    uint16_t raid_stride;               /* RAID stride */
-    uint16_t mmp_interval;              /* # seconds to wait in MMP checking */
-    uint64_t mmp_block;                 /* Block for multi-mount protection */
-    uint32_t raid_stripe_width;         /* Blocks on all data disks (N * stride) */
-    uint8_t log_groups_per_flex;        /* FLEX_BG group size */
-    uint8_t reserved_char_pad;
-    uint16_t reserved_pad;
-    uint64_t kbytes_written;            /* Number of lifetime kilobytes written */
-    uint32_t snapshot_inum;             /* I-node number of active snapshot */
-    uint32_t snapshot_id;               /* Sequential ID of active snapshot */
-    uint64_t snapshot_r_blocks_count;   /* Reserved blocks for active snapshot's future use */
-    uint32_t snapshot_list;             /* I-node number of the head of the on-disk snapshot list */
-    uint32_t error_count;               /* Number of file system errors */
-    uint32_t first_error_time;          /* First time an error happened */
-    uint32_t first_error_ino;           /* I-node involved in first error */
-    uint64_t first_error_block;         /* Block involved of first error */
-    uint8_t first_error_func[32];       /* Function where the error happened */
-    uint32_t first_error_line;          /* Line number where error happened */
-    uint32_t last_error_time;           /* Most recent time of an error */
-    uint32_t last_error_ino;            /* I-node involved in last error */
-    uint32_t last_error_line;           /* Line number where error happened */
-    uint64_t last_error_block;          /* Block involved of last error */
-    uint8_t last_error_func[32];        /* Function where the error happened */
-    uint8_t mount_opts[64];
-    uint32_t padding[112];              /* Padding to the end of the block */
-} __attribute__((packed));
-
-
-#define EXT4_SUPERBLOCK_MAGIC   0xEF53
-#define EXT4_SUPERBLOCK_SIZE    1024
-#define EXT4_SUPERBLOCK_OFFSET  1024
-
-#define EXT4_SUPERBLOCK_OS_LINUX  0
-#define EXT4_SUPERBLOCK_OS_HURD   1
-
-/*
- * Misc. filesystem flags
- */
-#define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH    0x0001  /* Signed dirhash in use */
-#define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH  0x0002  /* Unsigned dirhash in use */
-#define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS   0x0004  /* to test development code */
-
-/*
- * Filesystem states
- */
-#define EXT4_SUPERBLOCK_STATE_VALID_FS   0x0001  /* Unmounted cleanly */
-#define EXT4_SUPERBLOCK_STATE_ERROR_FS   0x0002  /* Errors detected */
-#define EXT4_SUPERBLOCK_STATE_ORPHAN_FS  0x0004  /* Orphans being recovered */
-
-/*
- * Behaviour when errors detected
- */
-#define EXT4_SUPERBLOCK_ERRORS_CONTINUE  1  /* Continue execution */
-#define EXT4_SUPERBLOCK_ERRORS_RO        2  /* Remount fs read-only */
-#define EXT4_SUPERBLOCK_ERRORS_PANIC     3  /* Panic */
-#define EXT4_SUPERBLOCK_ERRORS_DEFAULT   EXT4_ERRORS_CONTINUE
-
-/*
- * Compatible features
- */
-#define EXT4_FEATURE_COMPAT_DIR_PREALLOC   0x0001
-#define EXT4_FEATURE_COMPAT_IMAGIC_INODES  0x0002
-#define EXT4_FEATURE_COMPAT_HAS_JOURNAL    0x0004
-#define EXT4_FEATURE_COMPAT_EXT_ATTR       0x0008
-#define EXT4_FEATURE_COMPAT_RESIZE_INODE   0x0010
-#define EXT4_FEATURE_COMPAT_DIR_INDEX      0x0020
-
-/*
- * Read-only compatible features
- */
-#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER  0x0001
-#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE    0x0002
-#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR     0x0004
-#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE     0x0008
-#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM      0x0010
-#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK     0x0020
-#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE   0x0040
-
-/*
- * Incompatible features
- */
-#define EXT4_FEATURE_INCOMPAT_COMPRESSION  0x0001
-#define EXT4_FEATURE_INCOMPAT_FILETYPE     0x0002
-#define EXT4_FEATURE_INCOMPAT_RECOVER      0x0004  /* Needs recovery */
-#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV  0x0008  /* Journal device */
-#define EXT4_FEATURE_INCOMPAT_META_BG      0x0010
-#define EXT4_FEATURE_INCOMPAT_EXTENTS      0x0040  /* extents support */
-#define EXT4_FEATURE_INCOMPAT_64BIT        0x0080
-#define EXT4_FEATURE_INCOMPAT_MMP          0x0100
-#define EXT4_FEATURE_INCOMPAT_FLEX_BG      0x0200
-#define EXT4_FEATURE_INCOMPAT_EA_INODE     0x0400  /* EA in inode */
-#define EXT4_FEATURE_INCOMPAT_DIRDATA      0x1000  /* data in dirent */
-
-#define EXT4_FEATURE_COMPAT_SUPP  (EXT4_FEATURE_COMPAT_DIR_INDEX)
-
-#define EXT4_FEATURE_INCOMPAT_SUPP \
-        (EXT4_FEATURE_INCOMPAT_FILETYPE | \
-                EXT4_FEATURE_INCOMPAT_EXTENTS | \
-                EXT4_FEATURE_INCOMPAT_64BIT)
-
-#define EXT4_FEATURE_RO_COMPAT_SUPP \
-        (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
-                EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
-                EXT4_FEATURE_RO_COMPAT_HUGE_FILE | \
-                EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
-                EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \
-                EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
-
-struct ext4_fs {
-    struct ext4_blockdev	*bdev;
-    struct ext4_sblock  	sb;
-
-    uint64_t inode_block_limits[4];
-    uint64_t inode_blocks_per_level[4];
-};
-
-
-#define EXT4_BLOCK_GROUP_INODE_UNINIT   0x0001  /* Inode table/bitmap not in use */
-#define EXT4_BLOCK_GROUP_BLOCK_UNINIT   0x0002  /* Block bitmap not in use */
-#define EXT4_BLOCK_GROUP_ITABLE_ZEROED  0x0004  /* On-disk itable initialized to zero */
-
-/*
- * Structure of a blocks group descriptor
- */
-struct ext4_bgroup {
-    uint32_t block_bitmap_lo;             /* Blocks bitmap block */
-    uint32_t inode_bitmap_lo;             /* Inodes bitmap block */
-    uint32_t inode_table_first_block_lo;  /* Inodes table block */
-    uint16_t free_blocks_count_lo;        /* Free blocks count */
-    uint16_t free_inodes_count_lo;        /* Free inodes count */
-    uint16_t used_dirs_count_lo;          /* Directories count */
-    uint16_t flags;                       /* EXT4_BG_flags (INODE_UNINIT, etc) */
-    uint32_t reserved[2];                 /* Likely block/inode bitmap checksum */
-    uint16_t itable_unused_lo;            /* Unused inodes count */
-    uint16_t checksum;                    /* crc16(sb_uuid+group+desc) */
-
-    uint32_t block_bitmap_hi;             /* Blocks bitmap block MSB */
-    uint32_t inode_bitmap_hi;             /* I-nodes bitmap block MSB */
-    uint32_t inode_table_first_block_hi;  /* I-nodes table block MSB */
-    uint16_t free_blocks_count_hi;        /* Free blocks count MSB */
-    uint16_t free_inodes_count_hi;        /* Free i-nodes count MSB */
-    uint16_t used_dirs_count_hi;          /* Directories count MSB */
-    uint16_t itable_unused_hi;            /* Unused inodes count MSB */
-    uint32_t reserved2[3];                /* Padding */
-} ;
-
-struct ext4_block_group_ref {
-    struct ext4_block 	block;
-    struct ext4_bgroup 	*block_group;
-    struct ext4_fs  	*fs;
-    uint32_t 			index;
-    bool 				dirty;
-};
-
-#define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE  32
-#define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE  64
-
-#define EXT4_MIN_BLOCK_SIZE   1024   /* 1 KiB */
-#define EXT4_MAX_BLOCK_SIZE   65536  /* 64 KiB */
-#define EXT4_REV0_INODE_SIZE  128
-
-#define EXT4_INODE_BLOCK_SIZE  512
-
-#define EXT4_INODE_DIRECT_BLOCK_COUNT      12
-#define EXT4_INODE_INDIRECT_BLOCK          EXT4_INODE_DIRECT_BLOCK_COUNT
-#define EXT4_INODE_DOUBLE_INDIRECT_BLOCK   (EXT4_INODE_INDIRECT_BLOCK + 1)
-#define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK  (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
-#define EXT4_INODE_BLOCKS                  (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
-#define EXT4_INODE_INDIRECT_BLOCK_COUNT    (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
-
-/*
- * Structure of an inode on the disk
- */
-struct ext4_inode {
-    uint16_t mode;                       /* File mode */
-    uint16_t uid;                        /* Low 16 bits of owner uid */
-    uint32_t size_lo;                    /* Size in bytes */
-    uint32_t access_time;                /* Access time */
-    uint32_t change_inode_time;          /* I-node change time */
-    uint32_t modification_time;          /* Modification time */
-    uint32_t deletion_time;              /* Deletion time */
-    uint16_t gid;                        /* Low 16 bits of group id */
-    uint16_t links_count;                /* Links count */
-    uint32_t blocks_count_lo;            /* Blocks count */
-    uint32_t flags;                      /* File flags */
-    uint32_t unused_osd1;                /* OS dependent - not used in HelenOS */
-    uint32_t blocks[EXT4_INODE_BLOCKS];  /* Pointers to blocks */
-    uint32_t generation;                 /* File version (for NFS) */
-    uint32_t file_acl_lo;                /* File ACL */
-    uint32_t size_hi;
-    uint32_t obso_faddr;                 /* Obsoleted fragment address */
-
-    union {
-        struct {
-            uint16_t blocks_high;
-            uint16_t file_acl_high;
-            uint16_t uid_high;
-            uint16_t gid_high;
-            uint32_t reserved2;
-        } linux2;
-        struct {
-            uint16_t reserved1;
-            uint16_t mode_high;
-            uint16_t uid_high;
-            uint16_t gid_high;
-            uint32_t author;
-        } hurd2;
-    } __attribute__ ((packed)) osd2;
-
-    uint16_t extra_isize;
-    uint16_t pad1;
-    uint32_t ctime_extra;   /* Extra change time (nsec << 2 | epoch) */
-    uint32_t mtime_extra;   /* Extra Modification time (nsec << 2 | epoch) */
-    uint32_t atime_extra;   /* Extra Access time (nsec << 2 | epoch) */
-    uint32_t crtime;        /* File creation time */
-    uint32_t crtime_extra;  /* Extra file creation time (nsec << 2 | epoch) */
-    uint32_t version_hi;    /* High 32 bits for 64-bit version */
-} __attribute__ ((packed)) ;
-
-#define EXT4_INODE_MODE_FIFO       0x1000
-#define EXT4_INODE_MODE_CHARDEV    0x2000
-#define EXT4_INODE_MODE_DIRECTORY  0x4000
-#define EXT4_INODE_MODE_BLOCKDEV   0x6000
-#define EXT4_INODE_MODE_FILE       0x8000
-#define EXT4_INODE_MODE_SOFTLINK   0xA000
-#define EXT4_INODE_MODE_SOCKET     0xC000
-#define EXT4_INODE_MODE_TYPE_MASK  0xF000
-
-/*
- * Inode flags
- */
-#define EXT4_INODE_FLAG_SECRM      0x00000001  /* Secure deletion */
-#define EXT4_INODE_FLAG_UNRM       0x00000002  /* Undelete */
-#define EXT4_INODE_FLAG_COMPR      0x00000004  /* Compress file */
-#define EXT4_INODE_FLAG_SYNC       0x00000008  /* Synchronous updates */
-#define EXT4_INODE_FLAG_IMMUTABLE  0x00000010  /* Immutable file */
-#define EXT4_INODE_FLAG_APPEND     0x00000020  /* writes to file may only append */
-#define EXT4_INODE_FLAG_NODUMP     0x00000040  /* do not dump file */
-#define EXT4_INODE_FLAG_NOATIME    0x00000080  /* do not update atime */
-
-/* Compression flags */
-#define EXT4_INODE_FLAG_DIRTY     0x00000100
-#define EXT4_INODE_FLAG_COMPRBLK  0x00000200  /* One or more compressed clusters */
-#define EXT4_INODE_FLAG_NOCOMPR   0x00000400  /* Don't compress */
-#define EXT4_INODE_FLAG_ECOMPR    0x00000800  /* Compression error */
-
-#define EXT4_INODE_FLAG_INDEX         0x00001000  /* hash-indexed directory */
-#define EXT4_INODE_FLAG_IMAGIC        0x00002000  /* AFS directory */
-#define EXT4_INODE_FLAG_JOURNAL_DATA  0x00004000  /* File data should be journaled */
-#define EXT4_INODE_FLAG_NOTAIL        0x00008000  /* File tail should not be merged */
-#define EXT4_INODE_FLAG_DIRSYNC       0x00010000  /* Dirsync behaviour (directories only) */
-#define EXT4_INODE_FLAG_TOPDIR        0x00020000  /* Top of directory hierarchies */
-#define EXT4_INODE_FLAG_HUGE_FILE     0x00040000  /* Set to each huge file */
-#define EXT4_INODE_FLAG_EXTENTS       0x00080000  /* Inode uses extents */
-#define EXT4_INODE_FLAG_EA_INODE      0x00200000  /* Inode used for large EA */
-#define EXT4_INODE_FLAG_EOFBLOCKS     0x00400000  /* Blocks allocated beyond EOF */
-#define EXT4_INODE_FLAG_RESERVED      0x80000000  /* reserved for ext4 lib */
-
-#define EXT4_INODE_ROOT_INDEX  2
-
-struct ext4_inode_ref {
-    struct ext4_block 		 block;
-    struct ext4_inode 		*inode;
-    struct ext4_fs  *fs;
-    uint32_t index;
-    bool dirty;
-} ;
-
-
-#define EXT4_DIRECTORY_FILENAME_LEN  255
-
-#define EXT4_DIRECTORY_FILETYPE_UNKNOWN   0
-#define EXT4_DIRECTORY_FILETYPE_REG_FILE  1
-#define EXT4_DIRECTORY_FILETYPE_DIR       2
-#define EXT4_DIRECTORY_FILETYPE_CHRDEV    3
-#define EXT4_DIRECTORY_FILETYPE_BLKDEV    4
-#define EXT4_DIRECTORY_FILETYPE_FIFO      5
-#define EXT4_DIRECTORY_FILETYPE_SOCK      6
-#define EXT4_DIRECTORY_FILETYPE_SYMLINK   7
-
-/**
- * Linked list directory entry structure
- */
-struct ext4_directory_entry_ll {
-    uint32_t inode;         /* I-node for the entry */
-    uint16_t entry_length;  /* Distance to the next directory entry */
-    uint8_t name_length;    /* Lower 8 bits of name length */
-
-    union {
-        uint8_t name_length_high;  /* Higher 8 bits of name length */
-        uint8_t inode_type;        /* Type of referenced inode (in rev >= 0.5) */
-    } __attribute__ ((packed));
-
-    uint8_t name[EXT4_DIRECTORY_FILENAME_LEN];  /* Entry name */
-} __attribute__((packed)) ;
-
-struct ext4_directory_iterator {
-    struct ext4_inode_ref 			*inode_ref;
-    struct ext4_block 	   			current_block;
-    uint64_t 						current_offset;
-    struct ext4_directory_entry_ll  *current;
-};
-
-struct ext4_directory_search_result {
-    struct	ext4_block 		 		block;
-    struct  ext4_directory_entry_ll *dentry;
-};
-
-/* Structures for indexed directory */
-
-struct ext4_directory_dx_countlimit {
-    uint16_t limit;
-    uint16_t count;
-} ;
-
-struct ext4_directory_dx_dot_entry {
-    uint32_t inode;
-    uint16_t entry_length;
-    uint8_t name_length;
-    uint8_t inode_type;
-    uint8_t name[4];
-} ;
-
-struct ext4_directory_dx_root_info {
-    uint32_t reserved_zero;
-    uint8_t hash_version;
-    uint8_t info_length;
-    uint8_t indirect_levels;
-    uint8_t unused_flags;
-} ;
-
-struct ext4_directory_dx_entry {
-    uint32_t hash;
-    uint32_t block;
-} ;
-
-struct ext4_directory_dx_root {
-    struct ext4_directory_dx_dot_entry dots[2];
-    struct ext4_directory_dx_root_info info;
-    struct ext4_directory_dx_entry entries[0];
-};
-
-struct ext4_fake_directory_entry {
-    uint32_t inode;
-    uint16_t entry_length;
-    uint8_t name_length;
-    uint8_t inode_type;
-};
-
-struct ext4_directory_dx_node {
-    struct ext4_fake_directory_entry fake;
-    struct ext4_directory_dx_entry entries[0];
-};
-
-struct ext4_directory_dx_block {
-    struct ext4_block 		 	    block;
-    struct ext4_directory_dx_entry *entries;
-    struct ext4_directory_dx_entry *position;
-} ;
-
-#define EXT4_ERR_BAD_DX_DIR       (-75000)
-
-
-/*
- * This is the extent on-disk structure.
- * It's used at the bottom of the tree.
- */
-struct ext4_extent {
-    uint32_t first_block;  /* First logical block extent covers */
-    uint16_t block_count;  /* Number of blocks covered by extent */
-    uint16_t start_hi;     /* High 16 bits of physical block */
-    uint32_t start_lo;     /* Low 32 bits of physical block */
-} ;
-
-/*
- * This is index on-disk structure.
- * It's used at all the levels except the bottom.
- */
-struct ext4_extent_index {
-    uint32_t first_block;  /* Index covers logical blocks from 'block' */
-
-    /**
-     * Pointer to the physical block of the next
-     * level. leaf or next index could be there
-     * high 16 bits of physical block
-     */
-    uint32_t leaf_lo;
-    uint16_t leaf_hi;
-    uint16_t padding;
-} ;
-
-/*
- * Each block (leaves and indexes), even inode-stored has header.
- */
-struct ext4_extent_header {
-    uint16_t magic;
-    uint16_t entries_count;      /* Number of valid entries */
-    uint16_t max_entries_count;  /* Capacity of store in entries */
-    uint16_t depth;              /* Has tree real underlying blocks? */
-    uint32_t generation;         /* generation of the tree */
-} ;
-
-struct ext4_extent_path {
-    struct	ext4_block 		 	block;
-    uint16_t 					depth;
-    struct ext4_extent_header *header;
-    struct ext4_extent_index  *index;
-    struct ext4_extent 		  *extent;
-} ;
-
-#define EXT4_EXTENT_MAGIC  0xF30A
-
-#define	EXT4_EXTENT_FIRST(header) \
-        ((struct ext4_extent *) (((void *) (header)) + sizeof(struct ext4_extent_header)))
-
-#define	EXT4_EXTENT_FIRST_INDEX(header) \
-        ((struct ext4_extent_index *) (((void *) (header)) + sizeof(struct ext4_extent_header)))
-
-
-/* EXT3 HTree directory indexing */
-#define EXT2_HTREE_LEGACY					0
-#define EXT2_HTREE_HALF_MD4					1
-#define EXT2_HTREE_TEA						2
-#define EXT2_HTREE_LEGACY_UNSIGNED			3
-#define EXT2_HTREE_HALF_MD4_UNSIGNED		4
-#define EXT2_HTREE_TEA_UNSIGNED				5
-
-#define EXT2_HTREE_EOF 						0x7FFFFFFF
-
-
-struct ext4_hash_info {
-    uint32_t hash;
-    uint32_t minor_hash;
-    uint32_t hash_version;
-    const uint32_t *seed;
-};
-
-/*****************************************************************************/
-
-
-#ifdef CONFIG_BIG_ENDIAN
-static inline uint64_t to_le64(uint64_t n)
-{
-    return  ((n & 0xff) << 56) |
-            ((n & 0xff00) << 40) |
-            ((n & 0xff0000) << 24) |
-            ((n & 0xff000000LL) << 8) |
-            ((n & 0xff00000000LL) >> 8) |
-            ((n & 0xff0000000000LL) >> 24) |
-            ((n & 0xff000000000000LL) >> 40) |
-            ((n & 0xff00000000000000LL) >> 56);
-}
-
-static inline uint32_t to_le32(uint32_t n)
-{
-    return 	((n & 0xff) << 24) |
-            ((n & 0xff00) << 8) |
-            ((n & 0xff0000) >> 8) |
-            ((n & 0xff000000) >> 24);
-}
-
-static inline uint16_t to_le16(uint16_t n)
-{
-    return 	((n & 0xff) << 8) |
-            ((n & 0xff00) >> 8);
-}
-
-
-#else
-#define to_le64(_n)	_n
-#define to_le32(_n)	_n
-#define to_le16(_n)	_n
-#endif
-
-/****************************Access macros to ext4 structures*****************/
-
-#define ext4_get32(s, f)		to_le32((s)->f)
-#define ext4_get16(s, f)		to_le16((s)->f)
-#define ext4_get8(s, f)			(s)->f
-
-
-#define ext4_set32(s, f, v)		do { (s)->f = to_le32(v); }while(0)
-#define ext4_set16(s, f, v)		do { (s)->f = to_le16(v); }while(0)
-#define ext4_set8 (s, f, v)		do { (s)->f = (v); 		  }while(0)
-
-#endif /* EXT4_TYPES_H_ */
-
-/**
- * @}
- */
--- a/src/toolchain/bf518.cmake
+++ /dev/null
@@ -1,22 +1,0 @@
-# Name of the target
-SET(CMAKE_SYSTEM_NAME Generic)
-set(CMAKE_SYSTEM_PROCESSOR bf518)
-
-# Toolchain settings
-set(CMAKE_C_COMPILER 	bfin-elf-gcc)
-set(CMAKE_CXX_COMPILER	bfin-elf-g++)
-set(AS                  bfin-elf--gcc)
-set(AR			        bfin-elf-ar)
-set(OBJCOPY 		    bfin-elf-objcopy)
-set(OBJDUMP 		    bfin-elf-objdump)
-set(SIZE                bfin-elf-size)
-
-set(CMAKE_C_FLAGS   "-mcpu=bf518 -Wall -std=gnu99 -fdata-sections -ffunction-sections" CACHE INTERNAL "c compiler flags")
-set(CMAKE_CXX_FLAGS "-mcpu=bf518 -fno-builtin -Wall -fdata-sections -ffunction-sections" CACHE INTERNAL "cxx compiler flags")
-set(CMAKE_ASM_FLAGS "-mcpu=bf518 -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags")
-set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mcpu=bf592" CACHE INTERNAL "exe link flags")
-					
-							
-		
-		
-		
\ No newline at end of file
--- a/src/toolchain/cortex-m3.cmake
+++ /dev/null
@@ -1,18 +1,0 @@
-# Name of the target
-SET(CMAKE_SYSTEM_NAME Generic)
-set(CMAKE_SYSTEM_PROCESSOR cortex-m3)
-
-# Toolchain settings
-set(CMAKE_C_COMPILER 	arm-none-eabi-gcc)
-set(CMAKE_CXX_COMPILER 	arm-none-eabi-g++)
-set(AS 	                arm-none-eabi-as)
-set(AR         			arm-none-eabi-ar)
-set(OBJCOPY 	    	arm-none-eabi-objcopy)
-set(OBJDUMP     		arm-none-eabi-objdump)
-set(SIZE                arm-none-eabi-size)
-
-set(CMAKE_C_FLAGS   "-mthumb -mcpu=cortex-m3 -fno-builtin -Wall -std=gnu99 -fdata-sections -ffunction-sections" CACHE INTERNAL "c compiler flags")
-set(CMAKE_CXX_FLAGS "-mthumb -mcpu=cortex-m3 -fno-builtin -Wall -fdata-sections -ffunction-sections" CACHE INTERNAL "cxx compiler flags")
-set(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m3" CACHE INTERNAL "asm compiler flags")
-set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m3" CACHE INTERNAL "exe link flags")
-
--- a/src/toolchain/cortex-m4.cmake
+++ /dev/null
@@ -1,18 +1,0 @@
-# Name of the target
-SET(CMAKE_SYSTEM_NAME Generic)
-set(CMAKE_SYSTEM_PROCESSOR cortex-m4)
-
-# Toolchain settings
-set(CMAKE_C_COMPILER 	arm-none-eabi-gcc)
-set(CMAKE_CXX_COMPILER 	arm-none-eabi-g++)
-set(AS 	                arm-none-eabi-as)
-set(AR         			arm-none-eabi-ar)
-set(OBJCOPY 	    	arm-none-eabi-objcopy)
-set(OBJDUMP     		arm-none-eabi-objdump)
-set(SIZE                arm-none-eabi-size)
-
-set(CMAKE_C_FLAGS   "-mthumb -mcpu=cortex-m4 -fno-builtin -Wall -std=gnu99 -fdata-sections -ffunction-sections" CACHE INTERNAL "c compiler flags")
-set(CMAKE_CXX_FLAGS "-mthumb -mcpu=cortex-m4 -fno-builtin -Wall -fdata-sections -ffunction-sections" CACHE INTERNAL "cxx compiler flags")
-set(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m4" CACHE INTERNAL "asm compiler flags")
-set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m4" CACHE INTERNAL "exe link flags")
-
--- /dev/null
+++ b/toolchain/bf518.cmake
@@ -1,0 +1,22 @@
+# Name of the target
+SET(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR bf518)
+
+# Toolchain settings
+set(CMAKE_C_COMPILER 	bfin-elf-gcc)
+set(CMAKE_CXX_COMPILER	bfin-elf-g++)
+set(AS                  bfin-elf--gcc)
+set(AR			        bfin-elf-ar)
+set(OBJCOPY 		    bfin-elf-objcopy)
+set(OBJDUMP 		    bfin-elf-objdump)
+set(SIZE                bfin-elf-size)
+
+set(CMAKE_C_FLAGS   "-mcpu=bf518 -Wall -std=gnu99 -fdata-sections -ffunction-sections" CACHE INTERNAL "c compiler flags")
+set(CMAKE_CXX_FLAGS "-mcpu=bf518 -fno-builtin -Wall -fdata-sections -ffunction-sections" CACHE INTERNAL "cxx compiler flags")
+set(CMAKE_ASM_FLAGS "-mcpu=bf518 -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags")
+set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mcpu=bf592" CACHE INTERNAL "exe link flags")
+					
+							
+		
+		
+		
\ No newline at end of file
--- /dev/null
+++ b/toolchain/cortex-m3.cmake
@@ -1,0 +1,18 @@
+# Name of the target
+SET(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR cortex-m3)
+
+# Toolchain settings
+set(CMAKE_C_COMPILER 	arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER 	arm-none-eabi-g++)
+set(AS 	                arm-none-eabi-as)
+set(AR         			arm-none-eabi-ar)
+set(OBJCOPY 	    	arm-none-eabi-objcopy)
+set(OBJDUMP     		arm-none-eabi-objdump)
+set(SIZE                arm-none-eabi-size)
+
+set(CMAKE_C_FLAGS   "-mthumb -mcpu=cortex-m3 -fno-builtin -Wall -std=gnu99 -fdata-sections -ffunction-sections" CACHE INTERNAL "c compiler flags")
+set(CMAKE_CXX_FLAGS "-mthumb -mcpu=cortex-m3 -fno-builtin -Wall -fdata-sections -ffunction-sections" CACHE INTERNAL "cxx compiler flags")
+set(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m3" CACHE INTERNAL "asm compiler flags")
+set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m3" CACHE INTERNAL "exe link flags")
+
--- /dev/null
+++ b/toolchain/cortex-m4.cmake
@@ -1,0 +1,18 @@
+# Name of the target
+SET(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR cortex-m4)
+
+# Toolchain settings
+set(CMAKE_C_COMPILER 	arm-none-eabi-gcc)
+set(CMAKE_CXX_COMPILER 	arm-none-eabi-g++)
+set(AS 	                arm-none-eabi-as)
+set(AR         			arm-none-eabi-ar)
+set(OBJCOPY 	    	arm-none-eabi-objcopy)
+set(OBJDUMP     		arm-none-eabi-objdump)
+set(SIZE                arm-none-eabi-size)
+
+set(CMAKE_C_FLAGS   "-mthumb -mcpu=cortex-m4 -fno-builtin -Wall -std=gnu99 -fdata-sections -ffunction-sections" CACHE INTERNAL "c compiler flags")
+set(CMAKE_CXX_FLAGS "-mthumb -mcpu=cortex-m4 -fno-builtin -Wall -fdata-sections -ffunction-sections" CACHE INTERNAL "cxx compiler flags")
+set(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m4" CACHE INTERNAL "asm compiler flags")
+set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m4" CACHE INTERNAL "exe link flags")
+