Index: uspace/lib/ext4/libext4_block_group.c
===================================================================
--- uspace/lib/ext4/libext4_block_group.c	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/lib/ext4/libext4_block_group.c	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -48,5 +48,5 @@
 		ext4_superblock_t *sb)
 {
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		return ((uint64_t)uint32_t_le2host(bg->block_bitmap_hi) << 32) |
 			uint32_t_le2host(bg->block_bitmap_lo);
@@ -67,5 +67,5 @@
 	bg->block_bitmap_lo = host2uint32_t_le((block_bitmap << 32) >> 32);
 
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		bg->block_bitmap_hi = host2uint32_t_le(block_bitmap >> 32);
 	}
@@ -81,5 +81,5 @@
 		ext4_superblock_t *sb)
 {
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		return ((uint64_t)uint32_t_le2host(bg->inode_bitmap_hi) << 32) |
 			uint32_t_le2host(bg->inode_bitmap_lo);
@@ -101,5 +101,5 @@
 	bg->inode_bitmap_lo = host2uint32_t_le((inode_bitmap << 32) >> 32);
 
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		bg->inode_bitmap_hi = host2uint32_t_le(inode_bitmap >> 32);
 	}
@@ -115,5 +115,5 @@
 		ext4_superblock_t *sb)
 {
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		return ((uint64_t)uint32_t_le2host(bg->inode_table_first_block_hi) << 32) |
 			uint32_t_le2host(bg->inode_table_first_block_lo);
@@ -136,5 +136,5 @@
 
 	if (ext4_superblock_get_desc_size(sb) >
-			EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+			EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 
 		bg->inode_table_first_block_hi =
@@ -153,5 +153,5 @@
 {
 	if (ext4_superblock_get_desc_size(sb) >
-			EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+			EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 
 		return ((uint32_t)uint16_t_le2host(bg->free_blocks_count_hi) << 16) |
@@ -172,5 +172,5 @@
 {
 	bg->free_blocks_count_lo = host2uint16_t_le((value << 16) >> 16);
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		bg->free_blocks_count_hi = host2uint16_t_le(value >> 16);
 	}
@@ -186,5 +186,5 @@
 		ext4_superblock_t *sb)
 {
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		return ((uint32_t)uint16_t_le2host(bg->free_inodes_count_hi) << 16) |
 			uint16_t_le2host(bg->free_inodes_count_lo);
@@ -204,5 +204,5 @@
 {
 	bg->free_inodes_count_lo = host2uint16_t_le((value << 16) >> 16);
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		bg->free_inodes_count_hi = host2uint16_t_le(value >> 16);
 	}
@@ -218,5 +218,5 @@
 		ext4_superblock_t *sb)
 {
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		return ((uint32_t)uint16_t_le2host(bg->used_dirs_count_hi) << 16) |
 			uint16_t_le2host(bg->used_dirs_count_lo);
@@ -236,5 +236,5 @@
 {
 	bg->used_dirs_count_lo = host2uint16_t_le((count << 16) >> 16);
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		bg->used_dirs_count_hi = host2uint16_t_le(count >> 16);
 	}
@@ -270,5 +270,5 @@
 		ext4_superblock_t *sb)
 {
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		return ((uint32_t)uint16_t_le2host(bg->itable_unused_hi) << 16) |
 			uint16_t_le2host(bg->itable_unused_lo);
@@ -288,5 +288,5 @@
 {
 	bg->itable_unused_lo = host2uint16_t_le((value << 16) >> 16);
-	if (ext4_superblock_get_desc_size(sb) > EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
 		bg->itable_unused_hi = host2uint16_t_le(value >> 16);
 	}
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -95,4 +95,17 @@
 	fs->superblock = temp_superblock;
 
+	uint16_t state = ext4_superblock_get_state(fs->superblock);
+
+	if (state != EXT4_SUPERBLOCK_STATE_VALID_FS) {
+		return ENOTSUP;
+	}
+
+	// Mark system as mounted
+	ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
+	rc = ext4_superblock_write_direct(fs->device, fs->superblock);
+	if (rc != EOK) {
+		return rc;
+	}
+
 	return EOK;
 }
@@ -104,12 +117,11 @@
  * @return			error code
  */
-int ext4_filesystem_fini(ext4_filesystem_t *fs, bool write_sb)
+int ext4_filesystem_fini(ext4_filesystem_t *fs)
 {
 	int rc = EOK;
 
-	// If needed, write the superblock to the device
-	if (write_sb) {
-		rc = ext4_superblock_write_direct(fs->device, fs->superblock);
-	}
+	// Write the superblock to the device
+	ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS);
+	rc = ext4_superblock_write_direct(fs->device, fs->superblock);
 
 	// Release memory space for superblock
Index: uspace/lib/ext4/libext4_filesystem.h
===================================================================
--- uspace/lib/ext4/libext4_filesystem.h	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/lib/ext4/libext4_filesystem.h	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -38,5 +38,5 @@
 
 extern int ext4_filesystem_init(ext4_filesystem_t *, service_id_t);
-extern int ext4_filesystem_fini(ext4_filesystem_t *fs, bool);
+extern int ext4_filesystem_fini(ext4_filesystem_t *fs);
 extern int ext4_filesystem_check_sanity(ext4_filesystem_t *fs);
 extern int ext4_filesystem_check_features(ext4_filesystem_t *, bool *);
Index: uspace/lib/ext4/libext4_superblock.c
===================================================================
--- uspace/lib/ext4/libext4_superblock.c	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/lib/ext4/libext4_superblock.c	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -217,4 +217,54 @@
 }
 
+/** Get logarithmic fragment size (1024 << size)
+ *
+ * @param sb		superblock
+ * @return			logarithmic fragment size
+ */
+uint32_t ext4_superblock_get_log_frag_size(ext4_superblock_t *sb)
+{
+	return uint32_t_le2host(sb->log_frag_size);
+}
+
+/** Set logarithmic fragment size (1024 << size)
+ *
+ * @param sb		superblock
+ * @return			logarithmic fragment size
+ */
+
+void ext4_superblock_set_log_frag_size(ext4_superblock_t *sb, uint32_t frag_size)
+{
+	sb->log_frag_size = host2uint32_t_le(frag_size);
+}
+
+/** Get size of fragment (in bytes).
+ *
+ * @param sb		superblock
+ * @return			size of fragment
+ */
+uint32_t ext4_superblock_get_frag_size(ext4_superblock_t *sb)
+{
+	return 1024 << ext4_superblock_get_log_frag_size(sb);
+}
+
+/** Set size of fragment (in bytes).
+ *
+ * @param sb		superblock
+ * @param size		size of fragment (must be power of 2, at least 1024)
+ */
+void ext4_superblock_set_frag_size(ext4_superblock_t *sb, uint32_t size)
+{
+	uint32_t log = 0;
+	uint32_t tmp = size / EXT4_MIN_BLOCK_SIZE;
+
+	tmp >>= 1;
+	while (tmp) {
+		log++;
+		tmp >>= 1;
+	}
+
+	ext4_superblock_set_log_frag_size(sb, log);
+}
+
 /** Get number of data blocks per block group (except last BG)
  *
@@ -236,4 +286,25 @@
 	sb->blocks_per_group = host2uint32_t_le(blocks);
 }
+
+/** Get number of fragments per block group (except last BG)
+ *
+ * @param sb		superblock
+ * @return			fragments per block group
+ */
+uint32_t ext4_superblock_get_frags_per_group(ext4_superblock_t *sb)
+{
+	return uint32_t_le2host(sb->frags_per_group);
+}
+
+/** Set number of fragment per block group (except last BG)
+ *
+ * @param sb		superblock
+ * @param frags		fragments per block group
+ */
+void ext4_superblock_set_frags_per_group(ext4_superblock_t *sb, uint32_t frags)
+{
+	sb->frags_per_group = host2uint32_t_le(frags);
+}
+
 
 /** Get number of i-nodes per block group (except last BG)
@@ -796,6 +867,6 @@
 	uint16_t size = uint16_t_le2host(sb->desc_size);
 
-	if (size < EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
-		size = EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE;
+	if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
+		size = EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE;
 	}
 
@@ -812,6 +883,6 @@
 void ext4_superblock_set_desc_size(ext4_superblock_t *sb, uint16_t size)
 {
-	if (size < EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE) {
-		sb->desc_size = host2uint16_t_le(EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE);
+	if (size < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
+		sb->desc_size = host2uint16_t_le(EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE);
 	}
 
@@ -978,7 +1049,35 @@
 	}
 
-	// block size
-	// desc size
-
+	if (ext4_superblock_get_inodes_count(sb) == 0) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_blocks_count(sb) == 0) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_blocks_per_group(sb) == 0) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_inodes_per_group(sb) == 0) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_inode_size(sb) < 128) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_first_inode(sb) < 11) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_desc_size(sb) < EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE) {
+		return ENOTSUP;
+	}
+
+	if (ext4_superblock_get_desc_size(sb) > EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE) {
+		return ENOTSUP;
+	}
 
 	// TODO more checks !!!
Index: uspace/lib/ext4/libext4_superblock.h
===================================================================
--- uspace/lib/ext4/libext4_superblock.h	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/lib/ext4/libext4_superblock.h	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -55,6 +55,12 @@
 extern uint32_t ext4_superblock_get_block_size(ext4_superblock_t *);
 extern void ext4_superblock_set_block_size(ext4_superblock_t *, uint32_t);
+extern uint32_t ext4_superblock_get_log_frag_size(ext4_superblock_t *);
+extern void ext4_superblock_set_log_frag_size(ext4_superblock_t *, uint32_t);
+extern uint32_t ext4_superblock_get_frag_size(ext4_superblock_t *);
+extern void ext4_superblock_set_frag_size(ext4_superblock_t *, uint32_t);
 extern uint32_t ext4_superblock_get_blocks_per_group(ext4_superblock_t *);
 extern void ext4_superblock_set_blocks_per_group(ext4_superblock_t *, uint32_t);
+extern uint32_t ext4_superblock_get_frags_per_group(ext4_superblock_t *);
+extern void ext4_superblock_set_frags_per_group(ext4_superblock_t *, uint32_t);
 extern uint32_t ext4_superblock_get_inodes_per_group(ext4_superblock_t *);
 extern void ext4_superblock_set_inodes_per_group(ext4_superblock_t *, uint32_t);
Index: uspace/lib/ext4/libext4_types.h
===================================================================
--- uspace/lib/ext4/libext4_types.h	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/lib/ext4/libext4_types.h	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -47,7 +47,7 @@
 	uint32_t first_data_block; // First Data Block
 	uint32_t log_block_size; // Block size
-	uint32_t obso_log_frag_size; // Obsoleted fragment size
+	uint32_t log_frag_size; // Obsoleted fragment size
 	uint32_t blocks_per_group; // Number of blocks per group
-	uint32_t obso_frags_per_group; // Obsoleted fragments 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
@@ -265,6 +265,6 @@
 
 
-#define EXT4_BLOCK_MIN_GROUP_DESCRIPTOR_SIZE 32
-#define EXT4_BLOCK_MAX_GROUP_DESCRIPTOR_SIZE 64
+#define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32
+#define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64
 
 /*****************************************************************************/
Index: uspace/srv/fs/ext4fs/ext4fs_ops.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision d0c9b4b13f1b3e0359b91c17272add1187eda334)
+++ uspace/srv/fs/ext4fs/ext4fs_ops.c	(revision fb04cd903622a3c4f06209951d12543e563b5987)
@@ -936,5 +936,5 @@
 	rc = ext4_filesystem_check_sanity(fs);
 	if (rc != EOK) {
-		ext4_filesystem_fini(fs, false);
+		ext4_filesystem_fini(fs);
 		free(fs);
 		free(inst);
@@ -946,5 +946,5 @@
 	rc = ext4_filesystem_check_features(fs, &read_only);
 	if (rc != EOK) {
-		ext4_filesystem_fini(fs, false);
+		ext4_filesystem_fini(fs);
 		free(fs);
 		free(inst);
@@ -962,5 +962,5 @@
 	rc = ext4fs_node_get_core(&root_node, inst, EXT4_INODE_ROOT_INDEX);
 	if (rc != EOK) {
-		ext4_filesystem_fini(fs, false);
+		ext4_filesystem_fini(fs);
 		free(fs);
 		free(inst);
@@ -1015,5 +1015,5 @@
 	fibril_mutex_unlock(&open_nodes_lock);
 
-	return ext4_filesystem_fini(inst->filesystem, true);
+	return ext4_filesystem_fini(inst->filesystem);
 }
 
