ref: 3fff8b448fa9cfe2ff9c059b5eaf22c2735e7302
parent: 86b19bc444be3567974022cc76c4b58a48b500ff
author: ngkaho1234 <[email protected]>
date: Tue Oct 20 00:20:17 EDT 2015
Numorous patches on extents.c : 1. Rewrite the code logic of ext4_ext_remove_space 2. FIX: failing to modify a multi-level b+tree # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Your branch is up-to-date with 'origin/master'. # # Changes to be committed: # modified: extents.c #
--- a/lwext4/ext4_extent_full.c
+++ b/lwext4/ext4_extent_full.c
@@ -40,6 +40,7 @@
#include "ext4_extent.h"
+#define AGGRESSIVE_TEST
#if CONFIG_EXTENT_FULL
/*
@@ -178,6 +179,10 @@
size = (block_size - sizeof(struct ext4_extent_header)) /
sizeof(struct ext4_extent);
+#ifdef AGGRESSIVE_TEST
+ if (size > 6)
+ size = 6;
+#endif
return size;
}
@@ -188,6 +193,10 @@
size = (block_size - sizeof(struct ext4_extent_header)) /
sizeof(struct ext4_extent_index);
+#ifdef AGGRESSIVE_TEST
+ if (size > 5)
+ size = 5;
+#endif
return size;
}
@@ -198,6 +207,10 @@
size = sizeof(inode_ref->inode->blocks);
size -= sizeof(struct ext4_extent_header);
size /= sizeof(struct ext4_extent);
+#ifdef AGGRESSIVE_TEST
+ if (size > 3)
+ size = 3;
+#endif
return size;
}
@@ -208,6 +221,10 @@
size = sizeof(inode_ref->inode->blocks);
size -= sizeof(struct ext4_extent_header);
size /= sizeof(struct ext4_extent_index);
+#ifdef AGGRESSIVE_TEST
+ if (size > 4)
+ size = 4;
+#endif
return size;
}
@@ -742,7 +759,7 @@
err = EOK;
out:
- if (err != EOK) {
+ if (err != EOK || *need_grow) {
if (bh.lb_id)
ext4_block_set(inode_ref->fs->bdev, &bh);
@@ -841,6 +858,10 @@
ext4_ext_pblock(ex1))
return false;
+#ifdef AGGRESSIVE_TEST
+ if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) > 4)
+ return 0;
+#else
if (ext4_ext_is_unwritten(ex1)) {
if (ext4_ext_get_actual_len(ex1) +
ext4_ext_get_actual_len(ex2) >
@@ -849,6 +870,7 @@
} else if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) >
EXT_INIT_MAX_LEN)
return false;
+#endif
if (to_le32(ex2->first_block) + ext4_ext_get_actual_len(ex2) !=
to_le32(ex1->first_block))
@@ -864,6 +886,10 @@
ext4_ext_pblock(ex2))
return false;
+#ifdef AGGRESSIVE_TEST
+ if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) > 4)
+ return 0;
+#else
if (ext4_ext_is_unwritten(ex1)) {
if (ext4_ext_get_actual_len(ex1) +
ext4_ext_get_actual_len(ex2) >
@@ -872,6 +898,7 @@
} else if (ext4_ext_get_actual_len(ex1) + ext4_ext_get_actual_len(ex2) >
EXT_INIT_MAX_LEN)
return false;
+#endif
if (to_le32(ex1->first_block) + ext4_ext_get_actual_len(ex1) !=
to_le32(ex2->first_block))
@@ -1003,7 +1030,7 @@
err = EOK;
out:
- if (err != EOK) {
+ if (err != EOK || *need_grow) {
if (bh.lb_id)
ext4_block_set(inode_ref->fs->bdev, &bh);
@@ -1140,13 +1167,13 @@
static void ext4_ext_replace_path(struct ext4_inode_ref *inode_ref,
struct ext4_extent_path *path,
- struct ext_split_trans *spt, int32_t depth,
+ struct ext_split_trans *spt,
int32_t level)
{
+ int32_t depth = ext_depth(inode_ref->inode);
int32_t i = depth - level;
-
ext4_ext_drop_refs(inode_ref, path + i, 1);
- path[i] = spt->path;
+ path[i] = spt[level].path;
}
static int ext4_ext_insert_extent(struct ext4_inode_ref *inode_ref,
@@ -1234,7 +1261,7 @@
while (--level >= 0 && spt) {
if (spt[level].switch_to)
ext4_ext_replace_path(inode_ref, path, spt,
- depth, level);
+ level);
else if (spt[level].ptr)
ext4_ext_drop_refs(inode_ref, &spt[level].path,
1);
@@ -1367,6 +1394,8 @@
* remove it from index block above */
if (err == EOK && eh->entries_count == 0 && path[depth].block.lb_id)
err = ext4_ext_remove_idx(inode_ref, path, depth - 1);
+ else if (depth > 0)
+ path[depth - 1].index++;
return err;
}
@@ -1376,7 +1405,7 @@
if (!to_le16(path->header->entries_count))
return false;
- if (path->index >= EXT_LAST_INDEX(path->header))
+ if (path->index > EXT_LAST_INDEX(path->header))
return false;
if (to_le32(path->index->first_block) > to)
@@ -1458,10 +1487,14 @@
i++;
} else {
- if (!eh->entries_count && i > 0)
- ret = ext4_ext_remove_idx(inode_ref, path,
- i - 1);
+ if (i > 0) {
+ if (!eh->entries_count)
+ ret = ext4_ext_remove_idx(inode_ref, path,
+ i - 1);
+ else
+ path[i - 1].index++;
+ }
if (i)
ext4_block_set(inode_ref->fs->bdev,