[PATCH] UBIFS: improve znode splitting rules

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Artem Bityutskiy
Date: Tuesday, September 30, 2008 - 2:19 am

From: Adrian Hunter <ext-adrian.hunter@nokia.com>

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: Adrian Hunter <ext-adrian.hunter@nokia.com>
---
 fs/ubifs/tnc.c |   54 +++++++++++++++++++++++++++++++++---------------------
 1 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 66dc571..e0878a4 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -1962,7 +1962,7 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
 {
 	struct ubifs_znode *zn, *zi, *zp;
 	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);
 
@@ -2003,20 +2003,33 @@ again:
 	zn->level = znode->level;
 
 	/* Decide where to split */
-	if (znode->level == 0 && n == c->fanout &&
-	    key_type(c, key) == UBIFS_DATA_KEY) {
-		union ubifs_key *key1;
-
-		/*
-		 * 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;
-		if (key_inum(c, key1) == key_inum(c, key) &&
-		    key_type(c, key1) == UBIFS_DATA_KEY &&
-		    key_block(c, key1) == key_block(c, key) - 1)
-			appending = 1;
+	if (znode->level == 0 && key_type(c, key) == UBIFS_DATA_KEY) {
+		/* Try not to split consecutive data keys */
+		if (n == c->fanout) {
+			key1 = &znode->zbranch[n - 1].key;
+			if (key_inum(c, key1) == key_inum(c, key) &&
+			    key_type(c, key1) == UBIFS_DATA_KEY)
+				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) {
@@ -2046,6 +2059,8 @@ again:
 			zbr->znode->parent = zn;
 	}
 
+do_split:
+
 	__set_bit(DIRTY_ZNODE, &zn->flags);
 	atomic_long_inc(&c->dirty_zn_cnt);
 
@@ -2072,14 +2087,11 @@ again:
 
 	/* Insert new znode (produced by spitting) into the parent */
 	if (zp) {
-		i = n;
+		if (n == 0 && zi == znode && znode->iip == 0)
+			correct_parent_keys(c, znode);
+
 		/* Locate insertion point */
 		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 */
 		zbr->key = zn->zbranch[0].key;
-- 
1.5.4.1

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: What is in ubifs-2.6.git, Artem Bityutskiy, (Tue Sep 30, 12:56 am)
What is in ubifs-2.6.git, Artem Bityutskiy, (Tue Sep 30, 2:18 am)
[PATCH] UBIFS: add a print, fix comments and more minor stuff, Artem Bityutskiy, (Tue Sep 30, 2:18 am)
[PATCH] UBIFS: remove unneeded unlikely(), Artem Bityutskiy, (Tue Sep 30, 2:18 am)
[PATCH] UBIFS: inline one-line functions, Artem Bityutskiy, (Tue Sep 30, 2:18 am)
[PATCH] UBIFS: use an IS_ERR test rather than a NULL test, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: add bulk-read facility, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: add no_chk_data_crc mount option, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: improve znode splitting rules, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: check data CRC when in error state, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: use bit-fields when possible, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: correct key comparison, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: fix races in bit-fields, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: fix commentary, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: update dbg_dump_inode, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: correct comment for commit_on_unmount, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: commit on sync_fs, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: allow for sync_fs when read-only, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: improve garbage collection, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: fix bulk-read handling uptodate pages, Artem Bityutskiy, (Tue Sep 30, 2:19 am)
[PATCH] UBIFS: add more debugging messages for LPT, Artem Bityutskiy, (Tue Sep 30, 2:19 am)