ref: a997419af0b0974abce6cd984e3256776dde8c3f
parent: 700ad54c131fe037e5ca995b53cf698249e6b438
author: gkostka <kostka.grzegorz@gmail.com>
date: Fri May 30 12:35:37 EDT 2014
Merge bugfixes from HelenOS mainline.
--- a/lwext4/ext4_balloc.c
+++ b/lwext4/ext4_balloc.c
@@ -117,8 +117,10 @@
struct ext4_block bitmap_block;
rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
- if (rc != EOK)
+ if (rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
return rc;
+ }
/* Modify bitmap */
ext4_bmap_bit_clr(bitmap_block.data, index_in_group);
@@ -157,11 +159,7 @@
bg_ref.dirty = true;
/* Release block group reference */
- rc = ext4_fs_put_block_group_ref(&bg_ref);
- if (rc != EOK)
- return rc;
-
- return EOK;
+ return ext4_fs_put_block_group_ref(&bg_ref);
}
int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first,
@@ -194,8 +192,10 @@
struct ext4_block bitmap_block;
rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
- if (rc != EOK)
+ if (rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
return rc;
+ }
/* Modify bitmap */
ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, count);
@@ -232,23 +232,19 @@
bg_ref.dirty = true;
/* Release block group reference */
- rc = ext4_fs_put_block_group_ref(&bg_ref);
- if (rc != EOK)
- return rc;
-
- return EOK;
+ return ext4_fs_put_block_group_ref(&bg_ref);
}
/**@brief Compute 'goal' for allocation algorithm.
* @param inode_ref Reference to inode, to allocate block for
- * @return Goal block number
+ * @param goal
+ * @return error code
*/
-static uint32_t ext4_balloc_find_goal(struct ext4_inode_ref *inode_ref)
+static int ext4_balloc_find_goal(struct ext4_inode_ref *inode_ref, uint32_t *goal)
{
- uint32_t goal = 0;
-
struct ext4_sblock *sb = &inode_ref->fs->sb;
+ *goal = 0;
uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode);
uint32_t block_size = ext4_sb_get_block_size(sb);
@@ -260,13 +256,13 @@
/* 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);
+ inode_block_count - 1, goal);
if (rc != EOK)
- return 0;
+ return rc;
- if (goal != 0) {
- goal++;
- return goal;
+ if (*goal != 0) {
+ (*goal)++;
+ return rc;
}
/* If goal == 0, sparse file -> continue */
@@ -283,7 +279,7 @@
int rc = ext4_fs_get_block_group_ref(inode_ref->fs,
block_group, &bg_ref);
if (rc != EOK)
- return 0;
+ return rc;
/* Compute indexes */
uint32_t block_group_count = ext4_block_group_cnt(sb);
@@ -309,11 +305,9 @@
if (inode_table_bytes % block_size)
inode_table_blocks++;
- goal = inode_table_first_block + inode_table_blocks;
+ *goal = inode_table_first_block + inode_table_blocks;
- ext4_fs_put_block_group_ref(&bg_ref);
-
- return goal;
+ return ext4_fs_put_block_group_ref(&bg_ref);
}
@@ -323,14 +317,14 @@
uint32_t allocated_block = 0;
uint32_t bitmap_block_addr;
uint32_t rel_block_idx = 0;
-
+ uint32_t free_blocks;
+ uint32_t goal;
struct ext4_block bitmap_block;
- /* Find GOAL */
- uint32_t goal = ext4_balloc_find_goal(inode_ref);
- if (goal == 0) {
+ int rc = ext4_balloc_find_goal(inode_ref, &goal);
+ if (rc != EOK) {
/* no goal found => partition is full */
- return ENOSPC;
+ return rc;
}
struct ext4_sblock *sb = &inode_ref->fs->sb;
@@ -342,11 +336,18 @@
/* Load block group reference */
struct ext4_block_group_ref bg_ref;
- int rc = ext4_fs_get_block_group_ref(inode_ref->fs,
+ rc = ext4_fs_get_block_group_ref(inode_ref->fs,
block_group, &bg_ref);
if (rc != EOK)
return rc;
+ free_blocks =
+ ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
+ if (free_blocks == 0) {
+ /* This group has no free blocks */
+ goto goal_failed;
+ }
+
/* Compute indexes */
uint32_t first_in_group =
ext4_balloc_get_first_data_block_in_group(sb, &bg_ref);
@@ -432,9 +433,19 @@
}
/* No free block found yet */
- ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
- ext4_fs_put_block_group_ref(&bg_ref);
+ rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+ if(rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+goal_failed:
+
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
+ if(rc != EOK)
+ return rc;
+
+
/* Try other block groups */
uint32_t block_group_count = ext4_block_group_cnt(sb);
@@ -447,6 +458,13 @@
if (rc != EOK)
return rc;
+ free_blocks =
+ ext4_bg_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 =
ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
@@ -482,8 +500,10 @@
bitmap_block.dirty = true;
rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
- if (rc != EOK)
+ if (rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
return rc;
+ }
allocated_block =
ext4_fs_index_in_group2_baddr(sb, rel_block_idx,
@@ -492,9 +512,18 @@
goto success;
}
- ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
- ext4_fs_put_block_group_ref(&bg_ref);
+ rc = ext4_block_set(inode_ref->fs->bdev, &bitmap_block);
+ if(rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+next_group:
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
+ if(rc != EOK){
+ return rc;
+ }
+
/* Goto next group */
bgid = (bgid + 1) % block_group_count;
count--;
@@ -529,16 +558,16 @@
bg_ref.dirty = true;
- ext4_fs_put_block_group_ref(&bg_ref);
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
*fblock = allocated_block;
- return EOK;
+ return rc;
}
int ext4_balloc_try_alloc_block(struct ext4_inode_ref *inode_ref,
uint32_t baddr, bool *free)
{
- int rc = EOK;
+ int rc;
struct ext4_fs *fs = inode_ref->fs;
struct ext4_sblock *sb = &fs->sb;
@@ -562,8 +591,10 @@
struct ext4_block bitmap_block;
rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
- if (rc != EOK)
+ if (rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
return rc;
+ }
/* Check if block is free */
*free = ext4_bmap_is_bit_clr(bitmap_block.data, index_in_group);
--- a/lwext4/ext4_dir_idx.c
+++ b/lwext4/ext4_dir_idx.c
@@ -428,7 +428,7 @@
int rc = ext4_fs_get_inode_data_block_index(inode_ref,
block_idx, &block_addr);
- if (rc != EOK)
+ if(rc != EOK)
return rc;
@@ -440,10 +440,11 @@
p++;
/* Don't forget to put old block (prevent memory leak) */
- ext4_block_set(inode_ref->fs->bdev, &p->block);
+ rc = ext4_block_set(inode_ref->fs->bdev, &p->block);
+ if(rc != EOK)
+ return rc;
-
memcpy(&p->block, &p->block, sizeof(block));
p->entries = ((struct ext4_directory_dx_node *) block.data)->entries;
p->position = p->entries;
@@ -459,6 +460,7 @@
{
/* Load direct block 0 (index root) */
uint32_t root_block_addr;
+ int rc2;
int rc = ext4_fs_get_inode_data_block_index(inode_ref, 0,
&root_block_addr);
if (rc != EOK)
@@ -524,7 +526,9 @@
}
/* Not found, leave untouched */
- ext4_block_set(fs->bdev, &leaf_block);
+ rc2 = ext4_block_set(fs->bdev, &leaf_block);
+ if(rc2 != EOK)
+ goto cleanup;
if (rc != ENOENT)
goto cleanup;
@@ -539,12 +543,14 @@
/* Entry not found */
rc = ENOENT;
- cleanup:
+cleanup:
/* The whole path must be released (preventing memory leak) */
tmp = dx_blocks;
while (tmp <= dx_block) {
- ext4_block_set(fs->bdev, &tmp->block);
+ rc2 = ext4_block_set(fs->bdev, &tmp->block);
+ if (rc == EOK && rc2 != EOK)
+ rc = rc2;
++tmp;
}
--- a/lwext4/ext4_extent.c
+++ b/lwext4/ext4_extent.c
@@ -255,6 +255,7 @@
int ext4_extent_find_block(struct ext4_inode_ref *inode_ref, uint32_t iblock,
uint32_t *fblock)
{
+ int rc;
/* Compute bound defined by i-node size */
uint64_t inode_size =
ext4_inode_get_size(&inode_ref->fs->sb, inode_ref->inode);
@@ -285,8 +286,11 @@
/* Load child node and set values for the next iteration */
uint64_t child = ext4_extent_index_get_leaf(index);
- if (block.lb_id)
- ext4_block_set(inode_ref->fs->bdev, &block);
+ if (block.lb_id){
+ rc = ext4_block_set(inode_ref->fs->bdev, &block);
+ if(rc != EOK)
+ return rc;
+ }
int rc = ext4_block_get(inode_ref->fs->bdev, &block, child);
@@ -313,8 +317,11 @@
}
/* Cleanup */
- if (block.lb_id)
- ext4_block_set(inode_ref->fs->bdev, &block);
+ if (block.lb_id){
+ rc = ext4_block_set(inode_ref->fs->bdev, &block);
+ if(rc != EOK)
+ return rc;
+ }
return EOK;
}
@@ -389,8 +396,11 @@
* From 1: 0 is a block with inode data
*/
for (i = 1; i < tmp_path->depth; ++i) {
- if (tmp_path[i].block.lb_id)
- ext4_block_set(inode_ref->fs->bdev, &tmp_path[i].block);
+ if (tmp_path[i].block.lb_id){
+ int r = ext4_block_set(inode_ref->fs->bdev, &tmp_path[i].block);
+ if(r != EOK)
+ rc = r;
+ }
}
/* Destroy temporary data structure */
@@ -462,9 +472,7 @@
if (rc != EOK)
return rc;
- ext4_balloc_free_block(inode_ref, fblock);
-
- return EOK;
+ return ext4_balloc_free_block(inode_ref, fblock);
}
@@ -593,8 +601,11 @@
* starting from 1: 0 is a block with inode data
*/
for (i = 1; i <= path->depth; ++i) {
- if (path[i].block.lb_id)
- ext4_block_set(inode_ref->fs->bdev, &path[i].block);
+ if (path[i].block.lb_id){
+ int r = ext4_block_set(inode_ref->fs->bdev, &path[i].block);
+ if(r != EOK)
+ rc = r;
+ }
}
/* Destroy temporary data structure */
@@ -640,7 +651,11 @@
}
/* Put back not modified old block */
- ext4_block_set(inode_ref->fs->bdev, &path_ptr->block);
+ rc = ext4_block_set(inode_ref->fs->bdev, &path_ptr->block);
+ if (rc != EOK) {
+ ext4_balloc_free_block(inode_ref, fblock);
+ return rc;
+ }
/* Initialize newly allocated block and remember it */
memset(block.data, 0, block_size);
@@ -923,8 +938,11 @@
* starting from 1: 0 is a block with inode data
*/
for (i = 1; i <= path->depth; ++i) {
- if (path[i].block.lb_id)
- ext4_block_set(inode_ref->fs->bdev, &path[i].block);
+ if (path[i].block.lb_id){
+ int r = ext4_block_set(inode_ref->fs->bdev, &path[i].block);
+ if(r != EOK)
+ rc = r;
+ }
}
/* Destroy temporary data structure */
--- a/lwext4/ext4_ialloc.c
+++ b/lwext4/ext4_ialloc.c
@@ -192,8 +192,10 @@
struct ext4_block bitmap_block;
rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
- if (rc != EOK)
+ if (rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
return rc;
+ }
/* Try to allocate i-node in the bitmap */
uint32_t inodes_in_group = ext4_inodes_in_group_cnt(sb, bgid);
@@ -203,8 +205,16 @@
&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);
+ rc = ext4_block_set(fs->bdev, &bitmap_block);
+ if(rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
+ return rc;
+ }
+
+ rc = ext4_fs_put_block_group_ref(&bg_ref);
+ if (rc != EOK)
+ return rc;
+
continue;
}
@@ -214,8 +224,10 @@
bitmap_block.dirty = true;
ext4_block_set(fs->bdev, &bitmap_block);
- if (rc != EOK)
+ if (rc != EOK){
+ ext4_fs_put_block_group_ref(&bg_ref);
return rc;
+ }
/* Modify filesystem counters */
free_inodes--;
@@ -267,6 +279,9 @@
/* Block group not modified, put it and jump to the next block group */
ext4_fs_put_block_group_ref(&bg_ref);
+ if (rc != EOK)
+ return rc;
+
++bgid;
}