Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+33 −21
Original line number Diff line number Diff line
@@ -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 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
	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.
		 */
	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 &&
		    key_block(c, key1) == key_block(c, key) - 1)
			    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 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
			zbr->znode->parent = zn;
	}

do_split:

	__set_bit(DIRTY_ZNODE, &zn->flags);
	atomic_long_inc(&c->dirty_zn_cnt);

@@ -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 */
	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;