\r
uint16_t entry_space =\r
ext4_sb_get_block_size(&inode_ref->fs->sb) -\r
- sizeof(struct ext4_directory_dx_dot_entry);\r
+ sizeof(struct ext4_fake_directory_entry);\r
\r
entry_space = entry_space / sizeof(struct ext4_directory_dx_entry);\r
\r
void *entry_buffer_ptr = entry_buffer;\r
while ((void *)dentry < (void *)(old_data_block->data + block_size)) {\r
/* Read only valid entries */\r
- if (ext4_dir_entry_ll_get_inode(dentry) != 0) {\r
+ if (ext4_dir_entry_ll_get_inode(dentry) && dentry->name_length) {\r
uint8_t len = ext4_dir_entry_ll_get_name_length(\r
&inode_ref->fs->sb, dentry);\r
\r
uint32_t mid = 0;\r
uint32_t i;\r
for ( i = 0; i < idx; ++i) {\r
- if ((current_size + sort_array[i].rec_len) > (real_size / 2)) {\r
+ if ((current_size + sort_array[i].rec_len) > (block_size / 2)) {\r
new_hash = sort_array[i].hash;\r
mid = i;\r
break;\r
*/\r
static int ext4_dir_dx_split_index(struct ext4_inode_ref *inode_ref,\r
struct ext4_directory_dx_block *dx_blocks,\r
- struct ext4_directory_dx_block *dx_block)\r
+ struct ext4_directory_dx_block *dx_block,\r
+ struct ext4_directory_dx_block **new_dx_block)\r
{\r
struct ext4_directory_dx_entry *entries;\r
+\r
if (dx_block == dx_blocks)\r
entries =\r
((struct ext4_directory_dx_root *) dx_block->block.data)->entries;\r
struct ext4_directory_dx_node *new_node = (void *)new_block.data;\r
struct ext4_directory_dx_entry *new_entries = new_node->entries;\r
\r
+ memset(&new_node->fake, 0, sizeof(struct ext4_fake_directory_entry));\r
+\r
uint32_t block_size =\r
ext4_sb_get_block_size(&inode_ref->fs->sb);\r
\r
+ new_node->fake.entry_length = block_size;\r
+\r
/* Split leaf node */\r
if (levels > 0) {\r
uint32_t count_left = leaf_count / 2;\r
\r
/* Finally insert new entry */\r
ext4_dir_dx_insert_entry(dx_blocks, hash_right, new_iblock);\r
+ dx_blocks[0].block.dirty = true;\r
+ dx_blocks[1].block.dirty = true;\r
\r
+ new_block.dirty = true;\r
return ext4_block_set(inode_ref->fs->bdev, &new_block);\r
} else {\r
/* Create second level index */\r
\r
/* Add new entry to the path */\r
dx_block = dx_blocks + 1;\r
- dx_block->position = dx_block->position - entries + new_entries;\r
+ dx_block->position = dx_blocks->position - entries + new_entries;\r
dx_block->entries = new_entries;\r
dx_block->block = new_block;\r
+\r
+ *new_dx_block = dx_block;\r
+\r
+ dx_blocks[0].block.dirty = true;\r
+ dx_blocks[1].block.dirty = true;\r
}\r
}\r
\r
if (rc != EOK)\r
goto release_index;\r
\r
+ /*\r
+ * Check if there is needed to split index node\r
+ * (and recursively also parent nodes)\r
+ */\r
+ rc = ext4_dir_dx_split_index(parent, dx_blocks, dx_block, &dx_block);\r
+ if (rc != EOK)\r
+ goto release_target_index;\r
+\r
struct ext4_block target_block;\r
rc = ext4_block_get(fs->bdev, &target_block, leaf_block_addr);\r
if (rc != EOK)\r
goto release_index;\r
\r
+\r
/* Check if insert operation passed */\r
rc = ext4_dir_try_insert_entry(&fs->sb, &target_block, child,\r
name, name_len);\r
if (rc == EOK)\r
goto release_target_index;\r
\r
- /*\r
- * Check if there is needed to split index node\r
- * (and recursively also parent nodes)\r
- */\r
- rc = ext4_dir_dx_split_index(parent, dx_blocks, dx_block);\r
- if (rc != EOK)\r
- goto release_target_index;\r
\r
/* Split entries to two blocks (includes sorting by hash value) */\r
struct ext4_block new_block;\r
{\r
struct ext4_sblock *sb = &fs->sb;\r
\r
- uint32_t bgid = 0;\r
+ uint32_t bgid = fs->last_inode_bg_id;\r
uint32_t bg_count = ext4_block_group_cnt(sb);\r
uint32_t sb_free_inodes = ext4_get32(sb, free_inodes_count);\r
uint32_t avg_free_inodes = sb_free_inodes / bg_count;\r
+ bool rewind = false;\r
\r
/* Try to find free i-node in all block groups */\r
- while (bgid < bg_count) {\r
+ while (bgid <= bg_count) {\r
+\r
+ if(bgid == bg_count){\r
+ if(rewind)\r
+ break;\r
+ bg_count = fs->last_inode_bg_id;\r
+ bgid = 0;\r
+ rewind = true;\r
+ continue;\r
+ }\r
+\r
/* Load block group to check */\r
struct ext4_block_group_ref bg_ref;\r
int rc = ext4_fs_get_block_group_ref(fs, bgid, &bg_ref);\r
struct ext4_bgroup *bg = bg_ref.block_group;\r
\r
/* Read necessary values for algorithm */\r
- uint32_t free_blocks = ext4_bg_get_free_blocks_count(bg, sb);\r
uint32_t free_inodes = ext4_bg_get_free_inodes_count(bg, sb);\r
uint32_t used_dirs = ext4_bg_get_used_dirs_count(bg, sb);\r
\r
/* Check if this block group is good candidate for allocation */\r
- if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) {\r
+ if (free_inodes >= avg_free_inodes) {\r
/* Load block with bitmap */\r
uint32_t bitmap_block_addr = ext4_bg_get_inode_bitmap(\r
bg_ref.block_group, sb);\r
*index = ext4_ialloc_index_in_group2inode(sb,\r
index_in_group, bgid);\r
\r
+ fs->last_inode_bg_id = bgid;\r
+\r
return EOK;\r
}\r
\r