]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
When called from mk_incore_fstree, the startblock parameter is in increasing order.
authorMadan Valluri <mvalluri@sgi.com>
Wed, 9 Aug 2006 15:08:11 +0000 (15:08 +0000)
committerMadan Valluri <mvalluri@sgi.com>
Wed, 9 Aug 2006 15:08:11 +0000 (15:08 +0000)
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.

repair/incore.h
repair/incore_ext.c

index 80d94b1ad5f8b7d876598278639853248e009152..7783a6b69cfacdec6cbe2844da0fb13520282c12 100644 (file)
@@ -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 */
index d98f246e9a0b75308602cb0264f494a1a06f0618..a012d780e170ba625d07aa255661350bf003a456 100644 (file)
@@ -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;
 }