Index: uspace/lib/ext4/libext4_extent.c
===================================================================
--- uspace/lib/ext4/libext4_extent.c	(revision f2a3e579d2ad69d5f25f56410e84038e85892d89)
+++ uspace/lib/ext4/libext4_extent.c	(revision 7eb033ce26d136253e30c087e3f152a1089e3fed)
@@ -559,4 +559,5 @@
 		uint32_t iblock)
 {
+	EXT4FS_DBG("");
 	int rc;
 
@@ -568,4 +569,6 @@
 	// Trivial way - no splitting
 	if (entries < limit) {
+		EXT4FS_DBG("adding extent entry");
+
 		ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);
 		path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
@@ -581,8 +584,6 @@
 			ext4_superblock_get_block_size(inode_ref->fs->superblock);
 
-	// Trivial tree - grow
+	// Trivial tree - grow (extents were in root node)
 	if (path_ptr == path) {
-
-//		EXT4FS_DBG("splitting extent root");
 
 		uint32_t new_fblock;
@@ -592,6 +593,4 @@
 			return rc;
 		}
-
-//		EXT4FS_DBG("allocated new node \%u", new_fblock);
 
 		block_t *block;
@@ -641,10 +640,11 @@
 	}
 
+	assert(false);
+
 	// start splitting
 	uint32_t fblock = 0;
-
-	path_ptr--;
-
 	while (path_ptr > path) {
+
+		// TODO
 
 		rc = ext4_balloc_alloc_block(inode_ref, &fblock);
@@ -674,4 +674,62 @@
 			path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header);
 		}
+
+		path_ptr--;
+	}
+
+	// If splitting reached root node
+	if (path_ptr == path) {
+
+		uint32_t new_fblock;
+		rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);
+		if (rc != EOK) {
+			EXT4FS_DBG("error in block allocation");
+			return rc;
+		}
+
+		block_t *block;
+		rc = block_get(&block, inode_ref->fs->device,
+				new_fblock, BLOCK_FLAGS_NOREAD);
+		if (rc != EOK) {
+			EXT4FS_DBG("error in block_get");
+			return rc;
+		}
+
+		memset(block->data, 0, block_size);
+
+		// Move data from root to the new block
+		memcpy(block->data, inode_ref->inode->blocks,
+				EXT4_INODE_BLOCKS * sizeof(uint32_t));
+
+		path_ptr++;
+		path_ptr->block = block;
+		path_ptr->header = (ext4_extent_header_t *)block->data;
+		path_ptr->depth = ext4_extent_header_get_depth(path_ptr->header);
+		path_ptr->index = NULL;
+
+		uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);
+		path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;
+		ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);
+		uint16_t limit = (block_size - sizeof(ext4_extent_header_t)) /
+				sizeof(ext4_extent_t);
+		ext4_extent_header_set_max_entries_count(path_ptr->header, limit);
+
+		// Modify root (in inode)
+		path->depth = 1;
+		path->extent = NULL;
+		path->index = EXT4_EXTENT_FIRST_INDEX(path->header);
+
+		ext4_extent_header_set_depth(path->header, path_ptr->depth + 1);
+		ext4_extent_header_set_entries_count(path->header, 1);
+
+		ext4_extent_index_set_first_block(path->index, 0);
+		ext4_extent_index_set_leaf(path->index, new_fblock);
+
+		path_ptr->block->dirty = true;
+		path->block->dirty = true;
+
+		*last_path_item = path_ptr;
+
+		return EOK;
 	}
 
@@ -682,4 +740,5 @@
 		uint32_t *iblock, uint32_t *fblock)
 {
+	EXT4FS_DBG("");
 	int rc = EOK;
 
@@ -726,6 +785,5 @@
 			rc = ext4_balloc_alloc_block(inode_ref, &phys_block);
 			if (rc != EOK) {
-			// TODO error, cleanup
-				assert(false);
+				goto finish;
 			}
 
@@ -745,11 +803,9 @@
 			rc = ext4_balloc_try_alloc_block(inode_ref, phys_block, &free);
 			if (rc != EOK) {
-				// TODO error
-				assert(false);
+				goto finish;
 			}
 
 			if (! free) {
 				// target is not free
-//				EXT4FS_DBG("target not free, \%u", phys_block);
 				goto append_extent;
 			}
@@ -763,6 +819,4 @@
 		}
 	}
-
-	assert(false);
 
 append_extent:
@@ -776,6 +830,4 @@
 	}
 
-//	EXT4FS_DBG("allocated \%u", phys_block);
-
 	rc = ext4_extent_append_extent(inode_ref, path, &path_ptr, new_block_idx);
 	if (rc != EOK) {
@@ -794,6 +846,4 @@
 	*iblock = new_block_idx;
 	*fblock = phys_block;
-
-//	EXT4FS_DBG("iblock = \%u, fblock = \%u", new_block_idx, phys_block);
 
 	// Put loaded blocks
