]> git.neil.brown.name Git - LaFS.git/commitdiff
Set depth to 0 when InoIdx becomes empty.
authorNeilBrown <neilb@suse.de>
Tue, 8 Jun 2010 07:49:04 +0000 (17:49 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 8 Jun 2010 07:49:04 +0000 (17:49 +1000)
The code set depth to zero always, which is clearly broken.

We don't incrementally reduce the height of an indexing tree as it
shrinks.  Rather the high remains at the max until it is completely
empty, then it suddenly becomes zero.

Signed-off-by: NeilBrown <neilb@suse.de>
modify.c

index c89c3ac7aedd17c7070c79d4f8d2adcc1e4a4250..505a0c8f5efb68dac612fd6daff49b6339fdbfc3 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1845,18 +1845,22 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
         * resolve the parent in the same way.
         */
        if (test_bit(B_InoIdx, &ib->b.flags)) {
-               /* Empty InoIdx blocks aren't a problem, though I should
-                * probably reduce depth to 0 or 1.
+               /* Empty InoIdx blocks are allowed.  However depth must
+                * be zero.  This is where we suddenly collapse a now-empty
+                * indexing tree.
                 */
-               ib->depth = 0;
-               LAFSI(ib->b.inode)->depth = 0;
+               if ((ib->depth == 1 && lafs_leaf_next(ib, 0) == 0xFFFFFFFF) ||
+                   (ib->depth > 1 && lafs_index_empty(ib))) {
+                       ib->depth = 0;
+                       LAFSI(ib->b.inode)->depth = 0;
+               }
                /* Don't need to dirty the inode - the fact that we just
                 * did incorporation should ensure it is already dirty
                 */
                return;
        }
        if (!list_empty(&ib->children))
-               /* If there are child, we cannot treat this block as empty. */
+               /* If there are children, we cannot treat this block as empty. */
                return;
        if (ib->depth > 1 && ! lafs_index_empty(ib))
                return;