]> git.neil.brown.name Git - LaFS.git/commitdiff
Unpin data blocks from previous phase before allowing them to be dirty.
authorNeilBrown <neilb@suse.de>
Mon, 9 Aug 2010 10:24:20 +0000 (20:24 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 9 Aug 2010 10:24:20 +0000 (20:24 +1000)
While checkpointing will unpin PinPending blocks, it might not
manage to do it before the block gets Dirtied again.
So before we Pin the block - which is a required precursor to dirtying
them, unpin the block.

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

diff --git a/block.c b/block.c
index d64f25f730687c2b224bc0e87dc233082e6dd475..2070499edec0f7f2d17d933000df5941706a776a 100644 (file)
--- a/block.c
+++ b/block.c
@@ -465,6 +465,18 @@ lafs_pin_dblock(struct datablock *b, int alloc_type)
        if (LAFSI(b->b.inode)->type != TypeSegmentMap) {
                LAFS_BUG(!test_phase_locked(fs), &b->b);
                lafs_iolock_written(&b->b);
+               /* If this block is already pinned in the previous
+                * phase, now it a good time to flip it - we know it has
+                * been written and we want to flip it before it
+                * can be dirtied.
+                */
+               if (blk == &b->b &&
+                   test_bit(B_Pinned, &b->b.flags) &&
+                   !!test_bit(B_Phase1, &b->b.flags) != fs->phase) {
+                       clear_bit(B_PinPending, &b->b.flags);
+                       lafs_refile(&b->b, 0);
+                       set_bit(B_PinPending, &b->b.flags);
+               }
                lafs_iounlock_block(&b->b);
        }
 
index 4ab6b2c4b162f21cf9027795437fdd8c346f1829..36072bd2ad1fb79ff405f94e2cf897c6b17464df 100644 (file)
@@ -383,9 +383,9 @@ again:
                 * de-async them.
                 */
 
-               LAFS_BUG(!!test_bit(B_Phase1, &b->flags) != oldphase, b);
-
-               if (test_bit(B_PinPending, &b->flags) &&
+               if (!!test_bit(B_Phase1, &b->flags) != oldphase)
+                       /* lafs_pin_dblock flipped phase for us */;
+               else if (test_bit(B_PinPending, &b->flags) &&
                    !test_bit(B_Index, &b->flags) &&
                    (LAFSI(b->inode)->type == TypeSegmentMap ||
                     LAFSI(b->inode)->type == TypeQuota)) {