From: Madan Valluri Date: Wed, 9 Aug 2006 15:08:11 +0000 (+0000) Subject: When called from mk_incore_fstree, the startblock parameter is in increasing order. X-Git-Tag: v2.9.0~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b87887d426655b0e54e4a9b3d348efd0d819b769;p=thirdparty%2Fxfsprogs-dev.git When called from mk_incore_fstree, the startblock parameter is in increasing order. This means the new insert has to be at the end of the applicable bcnt extent list. The current implementation traverses the applicable bcnt extent list for each insert. The more the inserts, the longer it takes. Added last field to avl struct. --- diff --git a/repair/incore.h b/repair/incore.h index 80d94b1ad..7783a6b69 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -137,6 +137,7 @@ typedef struct extent_tree_node { extent_state_t ex_state; /* see state flags below */ struct extent_tree_node *next; /* for bcnt extent lists */ + struct extent_tree_node *last; /* for bcnt extent list anchors */ #if 0 xfs_ino_t ex_inode; /* owner, NULL if free or */ /* multiply allocated */ diff --git a/repair/incore_ext.c b/repair/incore_ext.c index d98f246e9..a012d780e 100644 --- a/repair/incore_ext.c +++ b/repair/incore_ext.c @@ -137,6 +137,7 @@ mk_extent_tree_nodes(xfs_agblock_t new_startblock, new->ex_blockcount = new_blockcount; new->ex_state = new_state; new->next = NULL; + new->last = NULL; return(new); } @@ -313,6 +314,25 @@ add_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, /* * avl tree code doesn't handle dups so insert * onto linked list in increasing startblock order + * + * when called from mk_incore_fstree, + * startblock is in increasing order. + * current is an "anchor" node. + * quick check if the new ext goes to the end. + * if so, append at the end, using the last field + * of the "anchor". + */ + ASSERT(current->last != NULL); + if (startblock > current->last->ex_startblock) { + current->last->next = ext; + current->last = ext; + return; + } + + /* + * scan, to find the proper location for new entry. + * this scan is *very* expensive and gets worse with + * with increasing entries. */ top = prev = current; while (current != NULL && @@ -324,6 +344,8 @@ add_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, if (top == current) { ASSERT(top == prev); /* + * new entry should be ahead of current. + * to keep the avl tree intact, * swap the values of to-be-inserted element * and the values of the head of the list. * then insert as the 2nd element on the list. @@ -357,6 +379,8 @@ add_bcnt_extent(xfs_agnumber_t agno, xfs_agblock_t startblock, do_error(_(": duplicate bno extent range\n")); } + ext->last = ext; /* ext is an "anchor" node */ + return; }