[Tux3] [PATCH] Fix entry table overflow (by splitting groups)
Shapor Naghibzadeh
shapor at gmail.com
Sat Aug 2 23:44:56 PDT 2008
# HG changeset patch
# User shapor at yzf.shapor.com
# Date 1217745661 25200
# Node ID 2c679288390fb11949fa30625be33b257db9ba02
# Parent e0d569213df6ba1ed4e8d2029b8de596f71403ca
Fix entry table overflow (by splitting groups).
Add ENOSPC check for leaf.
diff -r e0d569213df6 -r 2c679288390f test/fleaf.c
--- a/test/fleaf.c Sat Aug 02 13:52:11 2008 -0700
+++ b/test/fleaf.c Sat Aug 02 23:41:01 2008 -0700
@@ -199,18 +199,20 @@ int leaf_insert(struct leaf *leaf, block
unsigned loglo = target & 0xffffff, loghi = target >> 24;
void *used = leaf->used + (void *)leaf;
// need room for one extent + maybe one group + maybe one entry
+ if (leaf_free(leaf) < sizeof(struct extent) + sizeof(struct group) + sizeof(struct entry))
+ return -1;
/* find group position */
struct group *group;
for (group = groups; group > grbase; group--) {
- if (loghi <= group->loghi)
+ if (loghi < group->loghi || loghi == group->loghi && (group - 1 <= grbase || loghi != (group - 1)->loghi || loglo <= (entries - group->count)->loglo))
break;
extents += (entries - group->count)->limit;
entries -= group->count;
}
- /* insert new group if no match */
- if (group == grbase || loghi < group->loghi || group->count == 255) {
+ /* insert new group if no match or split is required */
+ if (group == grbase || loghi < group->loghi || (entries - group->count)->limit == 255) {
printf("new group at %i\n", group - grbase);
memmove(used - sizeof(*group), used, (void *)(group + 1) - used);
*group = (struct group){ .loghi = loghi, .count = 0 };
@@ -218,6 +220,16 @@ int leaf_insert(struct leaf *leaf, block
grbase--;
entries--;
leaf->groups++;
+ }
+
+ /* split the group if its out of space */
+ if ((entries - (group - 1)->count)->limit == 255) {
+ group->count = (group - 1)->count / 2;
+ struct entry *ep = entries - 1 - group->count;
+ int remove = (ep + 1)->limit;
+ while (ep > entries - 1 - (group - 1)->count)
+ (ep--)->limit -= remove;
+ (group - 1)->count -= group->count;
}
/* find entry position */
@@ -367,9 +379,12 @@ int main(int argc, char *argv[])
printf("--- leaf test ---\n");
unsigned hi = 1 << 24, hi2 = 3 * hi;
unsigned targets[] = { 0x11, 0x33, 0x22, hi2 + 0x44, hi2 + 0x55, hi2 + 0x44, hi + 0x33, hi + 0x44, hi + 0x99 }, next = 0;
- for (int i = 0; i < 260;i++)
- leaf_insert(leaf, i << 13, (struct extent){ .block = i });
- leaf_dump(leaf);
+ for (int j = 0; j < 2; j++) {
+ for (int i = 0; i < 130; i++)
+ for (int k = 0; k < 3; k++)
+ leaf_insert(leaf, (i * 2 + j) << 13, (struct extent){ .block = i, .version = k });
+ leaf_dump(leaf);
+ }
leaf_insert(leaf, targets[next++], (struct extent){ .block = 0x111 });
leaf_insert(leaf, targets[next++], (struct extent){ .block = 0x222 });
leaf_insert(leaf, targets[next++], (struct extent){ .block = 0x333 });
_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://tux3.org/cgi-bin/mailman/listinfo/tux3
More information about the Tux3
mailing list