Commit 2242c689 authored by Adrian Hunter's avatar Adrian Hunter Committed by Artem Bityutskiy

UBIFS: improve znode splitting rules

When inserting into a full znode it is split into two
znodes.  Because data node keys are usually consecutive,
it is better to try to keep them together.  This patch
does a better job of that.
Signed-off-by: default avatarAdrian Hunter <ext-adrian.hunter@nokia.com>
parent 2953e73f
...@@ -1962,7 +1962,7 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode, ...@@ -1962,7 +1962,7 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
{ {
struct ubifs_znode *zn, *zi, *zp; struct ubifs_znode *zn, *zi, *zp;
int i, keep, move, appending = 0; int i, keep, move, appending = 0;
union ubifs_key *key = &zbr->key; union ubifs_key *key = &zbr->key, *key1;
ubifs_assert(n >= 0 && n <= c->fanout); ubifs_assert(n >= 0 && n <= c->fanout);
...@@ -2003,20 +2003,33 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode, ...@@ -2003,20 +2003,33 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
zn->level = znode->level; zn->level = znode->level;
/* Decide where to split */ /* Decide where to split */
if (znode->level == 0 && n == c->fanout && if (znode->level == 0 && key_type(c, key) == UBIFS_DATA_KEY) {
key_type(c, key) == UBIFS_DATA_KEY) { /* Try not to split consecutive data keys */
union ubifs_key *key1; if (n == c->fanout) {
/*
* If this is an inode which is being appended - do not split
* it because no other zbranches can be inserted between
* zbranches of consecutive data nodes anyway.
*/
key1 = &znode->zbranch[n - 1].key; key1 = &znode->zbranch[n - 1].key;
if (key_inum(c, key1) == key_inum(c, key) && if (key_inum(c, key1) == key_inum(c, key) &&
key_type(c, key1) == UBIFS_DATA_KEY && key_type(c, key1) == UBIFS_DATA_KEY)
key_block(c, key1) == key_block(c, key) - 1)
appending = 1; appending = 1;
} else
goto check_split;
} else if (appending && n != c->fanout) {
/* Try not to split consecutive data keys */
appending = 0;
check_split:
if (n >= (c->fanout + 1) / 2) {
key1 = &znode->zbranch[0].key;
if (key_inum(c, key1) == key_inum(c, key) &&
key_type(c, key1) == UBIFS_DATA_KEY) {
key1 = &znode->zbranch[n].key;
if (key_inum(c, key1) != key_inum(c, key) ||
key_type(c, key1) != UBIFS_DATA_KEY) {
keep = n;
move = c->fanout - keep;
zi = znode;
goto do_split;
}
}
}
} }
if (appending) { if (appending) {
...@@ -2046,6 +2059,8 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode, ...@@ -2046,6 +2059,8 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
zbr->znode->parent = zn; zbr->znode->parent = zn;
} }
do_split:
__set_bit(DIRTY_ZNODE, &zn->flags); __set_bit(DIRTY_ZNODE, &zn->flags);
atomic_long_inc(&c->dirty_zn_cnt); atomic_long_inc(&c->dirty_zn_cnt);
...@@ -2072,14 +2087,11 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode, ...@@ -2072,14 +2087,11 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
/* Insert new znode (produced by spitting) into the parent */ /* Insert new znode (produced by spitting) into the parent */
if (zp) { if (zp) {
i = n; if (n == 0 && zi == znode && znode->iip == 0)
correct_parent_keys(c, znode);
/* Locate insertion point */ /* Locate insertion point */
n = znode->iip + 1; n = znode->iip + 1;
if (appending && n != c->fanout)
appending = 0;
if (i == 0 && zi == znode && znode->iip == 0)
correct_parent_keys(c, znode);
/* Tail recursion */ /* Tail recursion */
zbr->key = zn->zbranch[0].key; zbr->key = zn->zbranch[0].key;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment