]> git.neil.brown.name Git - LaFS.git/commitdiff
Fix Primary Ref counting when removing an unincorporated block.
authorNeilBrown <neilb@suse.de>
Wed, 9 Jun 2010 03:40:07 +0000 (13:40 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 13 Jun 2010 07:19:58 +0000 (17:19 +1000)
incorp_index did the wrong thing here, and we didn't differentiate
where in a primary_ref chain we were.
Fixed now I hope.

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

index 2d3ef24ccdefb4a0359741f6a37e5fccccf25454..f87c38a121aab1f6d59f138dd33ea14c094e2500 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1977,16 +1977,29 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
         * If no next, and parent not empty, just delete
         * If parent becomes empty, recurse upwards.
         */
+       nxt = NULL;
+       if (ib->b.siblings.next != &ib->b.parent->children)
+               nxt = list_entry(ib->b.siblings.next, struct indexblock, b.siblings);
        if (test_and_clear_bit(B_PrimaryRef, &ib->b.flags)) {
-               /* This was not incorporated yet */
-               int cr = incorp_index(&ib->b);
+               int cr = 0;
+               /* This was not incorporated yet, revert the uninc status */
+               if (nxt && test_bit(B_PrimaryRef, &nxt->b.flags)) {
+                       /* I was in a PrimaryRef chain */
+                       putiref(ib, MKREF(primary));
+               } else {
+                       struct indexblock *prev = list_entry(ib->b.siblings.prev,
+                                                            struct indexblock,
+                                                            b.siblings);
+                       putiref(prev, MKREF(primary));
+               }
                list_del_init(&ib->b.siblings);
+               clear_bit(B_Uninc, &ib->b.flags);
                if (test_and_clear_bit(B_Dirty, &ib->b.flags))
                        cr++;
+               if (test_and_clear_bit(B_UnincCredit, &ib->b.flags))
+                       cr++;
                lafs_space_return(fs, cr);
-       } else if (ib->b.siblings.next != &ib->b.parent->children &&
-                  (nxt = list_entry(ib->b.siblings.next, struct indexblock, b.siblings)) &&
-                  test_bit(B_PrimaryRef, &nxt->b.flags)) {
+       } else if (nxt && test_bit(B_PrimaryRef, &nxt->b.flags)) {
                /* Next block is not incorporated yet, so simply re-address
                 * it to replace this block.
                 */