]> git.neil.brown.name Git - LaFS.git/commitdiff
Handle index blocks becoming empty better.
authorNeilBrown <neilb@suse.de>
Mon, 28 Sep 2009 00:16:13 +0000 (10:16 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 28 Sep 2009 00:16:13 +0000 (10:16 +1000)
MORE TEXT HERE

index.c
modify.c

diff --git a/index.c b/index.c
index 5104687de1af1b54c5a723f5e86a8293ffc3e437..7d9ec0d3c20aab999a3933dda36e645eb1340f50 100644 (file)
--- a/index.c
+++ b/index.c
@@ -1305,6 +1305,7 @@ lafs_leaf_find(struct inode *inode, u32 addr, int adopt, u32 *next,
        BUG_ON(li->dblock == NULL);
        BUG_ON(atomic_read(&li->dblock->b.refcnt) == 0);
 
+ retry:
        if (next)
                *next = 0xFFFFFFFF;
 
@@ -1354,6 +1355,19 @@ lafs_leaf_find(struct inode *inode, u32 addr, int adopt, u32 *next,
                        dprintk("WARN %llu != %llu\n",
                                ib2->b.physaddr, iphys);
                }
+
+               if (test_bit(B_PhysValid, &ib2->b.flags) &&
+                   ib2->b.physaddr == 0) {
+                       /* this block has been invalidated, we must be
+                        * racing with some sort of truncate.
+                        * try again from the top.
+                        * FIXME should wait for something here.
+                        */
+                       putiref(ib2, REF);
+                       lafs_iounlock_block(&ib->b);
+                       putiref(ib, REF);
+                       goto retry;
+               }
 #ifdef FIXME
                if (!(ib2->b.flags & B_Linked)) {
                        struct block *b2 = peer_find(fs, inode->filesys,
index c4ccdaef21e10478699197a1b214dd1e22bf748d..2796c25430cb0c473410799d2222539b85fe9de6 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1790,18 +1790,22 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
        temp_credits = 0;
        lafs_space_return(fs, uit.credits);
 
-       /* If this index block is now empty, we clear
-        * B_Valid so that it doesn't get written out,
-        * but rather gets allocated as '0'.
+       /* If this internal index block is now empty, we either
+        * invalidate it or merge it with the first dependent block.
+        * If it is the first index block in it's parent we need to
+        * adjust the start of parent and possibly other ancestors,
+        * and incorporate them immediately.
         */
        if (test_bit(B_Valid, &ib->b.flags) &&
-           list_empty(&ib->children)) {
-               if (ib->depth == 1 &&
-                   lafs_leaf_next(ib, ib->b.fileaddr) == 0xFFFFFFFF)
-                       clear_bit(B_Valid, &ib->b.flags);
-               if (ib->depth > 1 &&
-                   lafs_index_empty(ib))
-                       clear_bit(B_Valid, &ib->b.flags);
+           list_empty(&ib->children) &&
+           ib->depth > 1 &&
+           lafs_index_empty(ib)) {
+               struct block *nxt = list_entry(ib->b.siblings.next,
+                                              struct block, siblings);
+               if (ib->b.siblings.next != &ib->b.parent->children &&
+                   test_bit(B_PrimaryRef, &nxt->flags)) {
+                       /* */
+               }
        }
 }