Index: uspace/lib/ext4/libext4_balloc.c
===================================================================
--- uspace/lib/ext4/libext4_balloc.c	(revision 38542dcb2946dff802762528d1ad1190b481d010)
+++ uspace/lib/ext4/libext4_balloc.c	(revision d579acce1df6462929e1e78b004f650a964db913)
@@ -91,6 +91,8 @@
 	block_t *bitmap_block;
 	rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
-	if (rc != EOK)
-		return rc;
+	if (rc != EOK) {
+		ext4_filesystem_put_block_group_ref(bg_ref);
+		return rc;
+	}
 	
 	/* Modify bitmap */
@@ -130,9 +132,5 @@
 	
 	/* Release block group reference */
-	rc = ext4_filesystem_put_block_group_ref(bg_ref);
-	if (rc != EOK)
-		return rc;
-	
-	return EOK;
+	return ext4_filesystem_put_block_group_ref(bg_ref);
 }
 
@@ -173,6 +171,8 @@
 	block_t *bitmap_block;
 	rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
-	if (rc != EOK)
-		return rc;
+	if (rc != EOK) {
+		ext4_filesystem_put_block_group_ref(bg_ref);
+		return rc;
+	}
 	
 	/* Modify bitmap */
@@ -212,9 +212,5 @@
 	
 	/* Release block group reference */
-	rc = ext4_filesystem_put_block_group_ref(bg_ref);
-	if (rc != EOK)
-		return rc;
-	
-	return EOK;
+	return ext4_filesystem_put_block_group_ref(bg_ref);
 }
 
@@ -264,8 +260,7 @@
  *
  */
-static uint32_t ext4_balloc_find_goal(ext4_inode_ref_t *inode_ref)
+static int ext4_balloc_find_goal(ext4_inode_ref_t *inode_ref, uint32_t *goal)
 {
-	uint32_t goal = 0;
-	
+	*goal = 0;
 	ext4_superblock_t *sb = inode_ref->fs->superblock;
 	
@@ -280,11 +275,11 @@
 	if (inode_block_count > 0) {
 		int rc = ext4_filesystem_get_inode_data_block_index(inode_ref,
-		    inode_block_count - 1, &goal);
+		    inode_block_count - 1, goal);
 		if (rc != EOK)
-			return 0;
+			return rc;
 		
 		if (goal != 0) {
-			goal++;
-			return goal;
+			(*goal)++;
+			return EOK;
 		}
 		
@@ -302,5 +297,5 @@
 	    block_group, &bg_ref);
 	if (rc != EOK)
-		return 0;
+		return rc;
 	
 	/* Compute indexes */
@@ -327,9 +322,7 @@
 		inode_table_blocks++;
 	
-	goal = inode_table_first_block + inode_table_blocks;
-	
-	ext4_filesystem_put_block_group_ref(bg_ref);
-	
-	return goal;
+	*goal = inode_table_first_block + inode_table_blocks;
+	
+	return ext4_filesystem_put_block_group_ref(bg_ref);
 }
 
@@ -349,12 +342,12 @@
 	block_t *bitmap_block;
 	uint32_t rel_block_idx = 0;
+	uint32_t free_blocks;
+	uint32_t goal;
 	
 	/* Find GOAL */
-	uint32_t goal = ext4_balloc_find_goal(inode_ref);
-	if (goal == 0) {
-		/* no goal found => partition is full */
-		return ENOSPC;
-	}
-	
+	int rc = ext4_balloc_find_goal(inode_ref, &goal);
+	if (rc != EOK)
+		return rc;
+
 	ext4_superblock_t *sb = inode_ref->fs->superblock;
 	
@@ -366,8 +359,15 @@
 	/* Load block group reference */
 	ext4_block_group_ref_t *bg_ref;
-	int rc = ext4_filesystem_get_block_group_ref(inode_ref->fs,
+	rc = ext4_filesystem_get_block_group_ref(inode_ref->fs,
 	    block_group, &bg_ref);
 	if (rc != EOK)
 		return rc;
+
+	free_blocks =
+	    ext4_block_group_get_free_blocks_count(bg_ref->block_group, sb);
+	if (free_blocks == 0) {
+		/* This group has no free blocks */
+		goto goal_failed;
+	}
 	
 	/* Compute indexes */
@@ -467,6 +467,15 @@
 	
 	/* No free block found yet */
-	block_put(bitmap_block);
-	ext4_filesystem_put_block_group_ref(bg_ref);
+	rc = block_put(bitmap_block);
+	if (rc != EOK) {
+		ext4_filesystem_put_block_group_ref(bg_ref);
+		return rc;
+	}
+
+goal_failed:
+
+	rc = ext4_filesystem_put_block_group_ref(bg_ref);
+	if (rc != EOK)
+		return rc;
 	
 	/* Try other block groups */
@@ -481,5 +490,12 @@
 		if (rc != EOK)
 			return rc;
-		
+
+		free_blocks =
+		     ext4_block_group_get_free_blocks_count(bg_ref->block_group, sb);
+		if (free_blocks == 0) {
+			/* This group has no free blocks */
+			goto next_group;
+		}
+
 		/* Load block with bitmap */
 		bitmap_block_addr =
@@ -512,6 +528,8 @@
 			bitmap_block->dirty = true;
 			rc = block_put(bitmap_block);
-			if (rc != EOK)
+			if (rc != EOK) {
+				ext4_filesystem_put_block_group_ref(bg_ref);
 				return rc;
+			}
 			
 			allocated_block =
@@ -528,6 +546,8 @@
 			bitmap_block->dirty = true;
 			rc = block_put(bitmap_block);
-			if (rc != EOK)
+			if (rc != EOK) {
+				ext4_filesystem_put_block_group_ref(bg_ref);
 				return rc;
+			}
 			
 			allocated_block =
@@ -538,6 +558,14 @@
 		}
 		
-		block_put(bitmap_block);
-		ext4_filesystem_put_block_group_ref(bg_ref);
+		rc = block_put(bitmap_block);
+		if (rc != EOK) {
+			ext4_filesystem_put_block_group_ref(bg_ref);
+			return rc;
+		}
+
+next_group:
+		rc = ext4_filesystem_put_block_group_ref(bg_ref);
+		if (rc != EOK)
+			return rc;
 		
 		/* Goto next group */
@@ -574,8 +602,8 @@
 	bg_ref->dirty = true;
 	
-	ext4_filesystem_put_block_group_ref(bg_ref);
+	rc = ext4_filesystem_put_block_group_ref(bg_ref);
 	
 	*fblock = allocated_block;
-	return EOK;
+	return rc;
 }
 
@@ -592,5 +620,5 @@
     bool *free)
 {
-	int rc = EOK;
+	int rc;
 	
 	ext4_filesystem_t *fs = inode_ref->fs;
@@ -613,6 +641,8 @@
 	block_t *bitmap_block;
 	rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0);
-	if (rc != EOK)
-		return rc;
+	if (rc != EOK) {
+		ext4_filesystem_put_block_group_ref(bg_ref);
+		return rc;
+	}
 	
 	/* Check if block is free */
