Index: uspace/lib/ext4/libext4_balloc.c
===================================================================
--- uspace/lib/ext4/libext4_balloc.c	(revision 865a4bfb2284aaa1b81c046adde866362404ab45)
+++ uspace/lib/ext4/libext4_balloc.c	(revision 4cdac6872dde2afba2d079b508504d95a25f4094)
@@ -40,44 +40,4 @@
 #include "libext4.h"
 
-/** Convert block address to relative index in block group.
- *
- * @param sb			superblock pointer
- * @param block_addr	block number to convert
- * @return				relative number of block
- */
-static uint32_t ext4_balloc_blockaddr2_index_in_group(ext4_superblock_t *sb,
-		uint32_t block_addr)
-{
-	uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
-	uint32_t first_block = ext4_superblock_get_first_data_block(sb);
-
-	/* First block == 0 or 1 */
-	if (first_block == 0) {
-		return block_addr % blocks_per_group;
-	} else {
-		return (block_addr - 1) % blocks_per_group;
-	}
-}
-
-/** Convert relative block number to absolute.
- *
- * @param sb			superblock pointer
- * @param index			relative index of block in group
- * @param bgid			index of block group
- * @return				absolute number of block
- */
-static uint32_t ext4_balloc_index_in_group2blockaddr(ext4_superblock_t *sb,
-		uint32_t index, uint32_t bgid)
-{
-	uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
-
-	if (ext4_superblock_get_first_data_block(sb) == 0) {
-		return bgid * blocks_per_group + index;
-	} else {
-		return bgid * blocks_per_group + index + 1;
-	}
-
-}
-
 /** Compute number of block group from block address.
  *
@@ -116,5 +76,6 @@
 	/* Compute indexes */
 	uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, block_addr);
-	uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, block_addr);
+	uint32_t index_in_group =
+			ext4_filesystem_blockaddr2_index_in_group(sb, block_addr);
 
 	/* Load block group reference */
@@ -213,5 +174,5 @@
 
 	uint32_t index_in_group_first =
-			ext4_balloc_blockaddr2_index_in_group(sb, first);
+			ext4_filesystem_blockaddr2_index_in_group(sb, first);
 
 
@@ -278,5 +239,5 @@
  * @return			absolute block index of first block
  */
-static uint32_t ext4_balloc_get_first_data_block_in_group(
+uint32_t ext4_balloc_get_first_data_block_in_group(
 		ext4_superblock_t *sb, ext4_block_group_ref_t *bg_ref)
 {
@@ -415,5 +376,6 @@
 	/* 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_balloc_blockaddr2_index_in_group(sb, goal);
+	uint32_t index_in_group =
+			ext4_filesystem_blockaddr2_index_in_group(sb, goal);
 
 
@@ -430,5 +392,5 @@
 			ext4_balloc_get_first_data_block_in_group(sb, bg_ref);
 
-	uint32_t first_in_group_index = ext4_balloc_blockaddr2_index_in_group(
+	uint32_t first_in_group_index = ext4_filesystem_blockaddr2_index_in_group(
 			sb, first_in_group);
 
@@ -460,5 +422,5 @@
 		}
 
-		allocated_block = ext4_balloc_index_in_group2blockaddr(
+		allocated_block = ext4_filesystem_index_in_group2blockaddr(
 							sb, index_in_group, block_group);
 
@@ -486,5 +448,5 @@
 			}
 
-			allocated_block = ext4_balloc_index_in_group2blockaddr(
+			allocated_block = ext4_filesystem_index_in_group2blockaddr(
 					sb, tmp_idx, block_group);
 
@@ -504,5 +466,5 @@
 		}
 
-		allocated_block = ext4_balloc_index_in_group2blockaddr(
+		allocated_block = ext4_filesystem_index_in_group2blockaddr(
 				sb, rel_block_idx, block_group);
 
@@ -520,5 +482,5 @@
 		}
 
-		allocated_block = ext4_balloc_index_in_group2blockaddr(
+		allocated_block = ext4_filesystem_index_in_group2blockaddr(
 				sb, rel_block_idx, block_group);
 
@@ -557,9 +519,9 @@
 		first_in_group = ext4_balloc_get_first_data_block_in_group(
 				sb, bg_ref);
-		index_in_group = ext4_balloc_blockaddr2_index_in_group(sb,
+		index_in_group = ext4_filesystem_blockaddr2_index_in_group(sb,
 						first_in_group);
 		blocks_in_group = ext4_superblock_get_blocks_in_group(sb, bgid);
 
-		first_in_group_index = ext4_balloc_blockaddr2_index_in_group(
+		first_in_group_index = ext4_filesystem_blockaddr2_index_in_group(
 			sb, first_in_group);
 
@@ -578,5 +540,5 @@
 			}
 
-			allocated_block = ext4_balloc_index_in_group2blockaddr(
+			allocated_block = ext4_filesystem_index_in_group2blockaddr(
 					sb, rel_block_idx, bgid);
 
@@ -594,5 +556,5 @@
 			}
 
-			allocated_block = ext4_balloc_index_in_group2blockaddr(
+			allocated_block = ext4_filesystem_index_in_group2blockaddr(
 					sb, rel_block_idx, bgid);
 
@@ -656,5 +618,6 @@
 	/* Compute indexes */
 	uint32_t block_group = ext4_balloc_get_bgid_of_block(sb, fblock);
-	uint32_t index_in_group = ext4_balloc_blockaddr2_index_in_group(sb, fblock);
+	uint32_t index_in_group =
+			ext4_filesystem_blockaddr2_index_in_group(sb, fblock);
 
 	/* Load block group reference */
Index: uspace/lib/ext4/libext4_balloc.h
===================================================================
--- uspace/lib/ext4/libext4_balloc.h	(revision 865a4bfb2284aaa1b81c046adde866362404ab45)
+++ uspace/lib/ext4/libext4_balloc.h	(revision 4cdac6872dde2afba2d079b508504d95a25f4094)
@@ -40,4 +40,6 @@
 extern int ext4_balloc_free_blocks(ext4_inode_ref_t *,
 		uint32_t , uint32_t);
+extern uint32_t ext4_balloc_get_first_data_block_in_group(
+		ext4_superblock_t *, ext4_block_group_ref_t *);
 extern int ext4_balloc_alloc_block(ext4_inode_ref_t *, uint32_t *);
 extern int ext4_balloc_try_alloc_block(ext4_inode_ref_t *, uint32_t, bool *);
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision 865a4bfb2284aaa1b81c046adde866362404ab45)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision 4cdac6872dde2afba2d079b508504d95a25f4094)
@@ -78,5 +78,5 @@
 
 	/* Initialize block caching by libblock */
-	rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_WT);
+	rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_WB);
 	if (rc != EOK) {
 		block_fini(fs->device);
@@ -104,5 +104,5 @@
 		block_cache_fini(fs->device);
 		block_fini(fs->device);
-		EXT4FS_DBG("invalid state error");
+		EXT4FS_DBG("Unable to mount: Invalid state error");
 		return ENOTSUP;
 	}
@@ -117,4 +117,7 @@
 		return rc;
 	}
+
+	uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
+	ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
 
 	return EOK;
@@ -189,4 +192,5 @@
 	incompatible_features &= ~EXT4_FEATURE_INCOMPAT_SUPP;
 	if (incompatible_features > 0) {
+		EXT4FS_DBG("Not supported incompatible features");
 		return ENOTSUP;
 	}
@@ -199,6 +203,198 @@
 	compatible_read_only &= ~EXT4_FEATURE_RO_COMPAT_SUPP;
 	if (compatible_read_only > 0) {
+		EXT4FS_DBG("Not supported readonly features - mounting READ-ONLY");
 		*read_only = true;
 		return EOK;
+	}
+
+	return EOK;
+}
+
+
+/** Convert block address to relative index in block group.
+ *
+ * @param sb			superblock pointer
+ * @param block_addr	block number to convert
+ * @return				relative number of block
+ */
+uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *sb,
+		uint32_t block_addr)
+{
+	uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
+	uint32_t first_block = ext4_superblock_get_first_data_block(sb);
+
+	/* First block == 0 or 1 */
+	if (first_block == 0) {
+		return block_addr % blocks_per_group;
+	} else {
+		return (block_addr - 1) % blocks_per_group;
+	}
+}
+
+
+/** Convert relative block address in group to absolute address.
+ *
+ * @param sb			superblock pointer
+ * @param block_addr	block number to convert
+ * @return				absolute block address
+ */
+uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *sb,
+		uint32_t index, uint32_t bgid)
+{
+	uint32_t blocks_per_group = ext4_superblock_get_blocks_per_group(sb);
+
+	if (ext4_superblock_get_first_data_block(sb) == 0) {
+		return bgid * blocks_per_group + index;
+	} else {
+		return bgid * blocks_per_group + index + 1;
+	}
+
+}
+
+/** Initialize block bitmap in block group.
+ * 
+ * @param bg_ref	reference to block group
+ * @return			error code
+ */
+static int ext4_filesystem_init_block_bitmap(ext4_block_group_ref_t *bg_ref)
+{
+	int rc;
+
+	/* Load bitmap */
+	uint32_t bitmap_block_addr = ext4_block_group_get_block_bitmap(
+			bg_ref->block_group, bg_ref->fs->superblock);
+	block_t *bitmap_block;
+
+	rc = block_get(&bitmap_block, bg_ref->fs->device,
+			bitmap_block_addr, BLOCK_FLAGS_NOREAD);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	uint8_t *bitmap = bitmap_block->data;
+
+	/* Initialize all bitmap bits to zero */
+	uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
+	memset(bitmap, 0, block_size);
+
+	/* 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->superblock, bg_ref);
+	uint32_t first_data_idx = ext4_filesystem_blockaddr2_index_in_group(
+			bg_ref->fs->superblock, first_data);
+
+	/* Set bits from to first block to first data block - 1 to one (allocated) */
+	for (uint32_t block = first_idx; block < first_data_idx; ++block) {
+		ext4_bitmap_set_bit(bitmap, block);
+	}
+
+	bitmap_block->dirty = true;
+
+	/* Save bitmap */
+	rc = block_put(bitmap_block);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return EOK;
+}
+
+/** Initialize i-node bitmap in block group.
+ * 
+ * @param bg_ref	reference to block group
+ * @return			error code
+ */
+static int ext4_filesystem_init_inode_bitmap(ext4_block_group_ref_t *bg_ref)
+{
+	int rc;
+
+	/* Load bitmap */
+	uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
+			bg_ref->block_group, bg_ref->fs->superblock);
+	block_t *bitmap_block;
+
+	rc = block_get(&bitmap_block, bg_ref->fs->device,
+			bitmap_block_addr, BLOCK_FLAGS_NOREAD);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	uint8_t *bitmap = bitmap_block->data;
+
+	/* Initialize all bitmap bits to zero */
+	uint32_t block_size = ext4_superblock_get_block_size(bg_ref->fs->superblock);
+	uint32_t inodes_per_group =
+			ext4_superblock_get_inodes_per_group(bg_ref->fs->superblock);
+	memset(bitmap, 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_bitmap_set_bit(bitmap, i);
+	}
+
+	if (i < end_bit) {
+		memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+	}
+
+	bitmap_block->dirty = true;
+
+	/* Save bitmap */
+	rc = block_put(bitmap_block);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return EOK;
+}
+
+/** Initialize i-node table in block group.
+ * 
+ * @param bg_ref	reference to block group
+ * @return			error code
+ */static int ext4_filesystem_init_inode_table(ext4_block_group_ref_t *bg_ref)
+{
+	int rc;
+
+	ext4_superblock_t *sb = bg_ref->fs->superblock;
+
+	uint32_t inode_size = ext4_superblock_get_inode_size(sb);
+	uint32_t block_size = ext4_superblock_get_block_size(sb);
+	uint32_t inodes_per_block = block_size / inode_size;
+
+	uint32_t inodes_in_group =
+			ext4_superblock_get_inodes_in_group(sb, bg_ref->index);
+
+	uint32_t table_blocks = inodes_in_group / inodes_per_block;
+
+	if (inodes_in_group % inodes_per_block) {
+		table_blocks++;
+	}
+
+	/* Compute initialization bounds */
+	uint32_t first_block = ext4_block_group_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 (uint32_t fblock = first_block; fblock <= last_block; ++fblock) {
+		block_t *block;
+		rc = block_get(&block, bg_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD);
+		if (rc != EOK) {
+			return rc;
+		}
+
+		memset(block->data, 0, block_size);
+		block->dirty = true;
+
+		rc = block_put(block);
+		if (rc != EOK) {
+			return rc;
+		}
 	}
 
@@ -249,4 +445,52 @@
 
 	*ref = newref;
+
+	if (ext4_block_group_has_flag(newref->block_group,
+			EXT4_BLOCK_GROUP_BLOCK_UNINIT)) {
+
+		rc = ext4_filesystem_init_block_bitmap(newref);
+		if (rc != EOK) {
+			block_put(newref->block);
+			free(newref);
+			return rc;
+		}
+		ext4_block_group_clear_flag(newref->block_group,
+				EXT4_BLOCK_GROUP_BLOCK_UNINIT);
+
+		newref->dirty = true;
+	}
+
+	if (ext4_block_group_has_flag(newref->block_group,
+			EXT4_BLOCK_GROUP_INODE_UNINIT)) {
+
+		rc = ext4_filesystem_init_inode_bitmap(newref);
+		if (rc != EOK) {
+			block_put(newref->block);
+			free(newref);
+			return rc;
+		}
+
+		ext4_block_group_clear_flag(newref->block_group,
+				EXT4_BLOCK_GROUP_INODE_UNINIT);
+
+		ext4_block_group_set_itable_unused(newref->block_group,
+				newref->fs->superblock, 0);
+
+
+		if (! ext4_block_group_has_flag(newref->block_group,
+				EXT4_BLOCK_GROUP_ITABLE_ZEROED)) {
+
+			rc = ext4_filesystem_init_inode_table(newref);
+			if (rc != EOK) {
+				return rc;
+			}
+
+			ext4_block_group_set_flag(newref->block_group,
+					EXT4_BLOCK_GROUP_ITABLE_ZEROED);
+
+		}
+		newref->dirty = true;
+
+	}
 
 	return EOK;
@@ -1168,7 +1412,4 @@
 int ext4_filesystem_add_orphan(ext4_inode_ref_t *inode_ref)
 {
-
-	EXT4FS_DBG("adding orphan \%u", inode_ref->index);
-
 	uint32_t next_orphan = ext4_superblock_get_last_orphan(
 			inode_ref->fs->superblock);
@@ -1192,7 +1433,4 @@
 int ext4_filesystem_delete_orphan(ext4_inode_ref_t *inode_ref)
 {
-
-	EXT4FS_DBG("adding orphan \%u", inode_ref->index);
-
 	int rc;
 
Index: uspace/lib/ext4/libext4_filesystem.h
===================================================================
--- uspace/lib/ext4/libext4_filesystem.h	(revision 865a4bfb2284aaa1b81c046adde866362404ab45)
+++ uspace/lib/ext4/libext4_filesystem.h	(revision 4cdac6872dde2afba2d079b508504d95a25f4094)
@@ -41,4 +41,8 @@
 extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs);
 extern int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
+extern uint32_t ext4_filesystem_blockaddr2_index_in_group(ext4_superblock_t *,
+		uint32_t);
+extern uint32_t ext4_filesystem_index_in_group2blockaddr(ext4_superblock_t *,
+		uint32_t, uint32_t);
 extern int ext4_filesystem_get_block_group_ref(ext4_filesystem_t *, uint32_t,
     ext4_block_group_ref_t **);
Index: uspace/lib/ext4/libext4_ialloc.c
===================================================================
--- uspace/lib/ext4/libext4_ialloc.c	(revision 865a4bfb2284aaa1b81c046adde866362404ab45)
+++ uspace/lib/ext4/libext4_ialloc.c	(revision 4cdac6872dde2afba2d079b508504d95a25f4094)
@@ -141,12 +141,4 @@
 			sb, free_inodes);
 
-	/* Set unused i-nodes count if supported */
-	if (ext4_block_group_has_flag(bg_ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT)) {
-		uint32_t unused_inodes = ext4_block_group_get_itable_unused(
-				bg_ref->block_group, sb);
-		unused_inodes++;
-		ext4_block_group_set_itable_unused(bg_ref->block_group, sb, unused_inodes);
-	}
-
 	bg_ref->dirty = true;
 
@@ -241,11 +233,4 @@
 			ext4_block_group_set_free_inodes_count(bg, sb, free_inodes);
 
-			/* Decrement unused i-nodes counter if supported */
-			if (ext4_block_group_has_flag(bg, EXT4_BLOCK_GROUP_INODE_UNINIT)) {
-				uint16_t unused_inodes = ext4_block_group_get_itable_unused(bg, sb);
-				unused_inodes--;
-				ext4_block_group_set_itable_unused(bg, sb, unused_inodes);
-			}
-
 			/* Increment used directories counter */
 			if (is_dir) {
