]> git.neil.brown.name Git - LaFS.git/commitdiff
Extend coverage of IOLock
authorNeilBrown <neilb@suse.de>
Thu, 19 Mar 2009 01:41:22 +0000 (12:41 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 19 Mar 2009 01:41:22 +0000 (12:41 +1100)
IOLock now needs to be held on
erase_iblock phase_flip allocated_block

This avoid recursive issues as e.g. erase_iblock was sometimes
called with IOLock held and sometimes not.

block.c
index.c
inode.c
roll.c

diff --git a/block.c b/block.c
index a1ed20310c57a51f67fa62fafc18327537885c2c..a54720fb2f8e2ed5a40f61d8b63675cd88c6d59d 100644 (file)
--- a/block.c
+++ b/block.c
@@ -529,7 +529,6 @@ lafs_erase_dblock(struct datablock *b)
        if (test_and_clear_bit(B_Prealloc, &b->b.flags))
                if (b->b.physaddr == 0)
                        lafs_summary_allocate(fs, b->b.inode, -1);
-       lafs_iounlock_block(&b->b, 0);
 
        if (b->b.physaddr)
                lafs_allocated_block(fs, &b->b, 0);
@@ -538,6 +537,7 @@ lafs_erase_dblock(struct datablock *b)
                        lafs_space_return(fs, 1);
                printk("Erased unwritten block (p=%p) %s\n", b->b.parent, strblk(&b->b));
        }
+       lafs_iounlock_block(&b->b, 0);
 }
 
 void
@@ -545,13 +545,12 @@ lafs_erase_iblock(struct indexblock *b)
 {
        struct fs *fs = fs_from_inode(b->b.inode);
 
-       lafs_iolock_block(&b->b);
+       BUG_ON(!test_bit(B_IOLock, &b->b.flags));
        clear_bit(B_Valid, &b->b.flags);
        if (test_and_clear_bit(B_Dirty, &b->b.flags))
                lafs_space_return(fs, 1);
        if (test_and_clear_bit(B_Realloc, &b->b.flags))
                lafs_space_return(fs, 1);
-       lafs_iounlock_block(&b->b, 0);
 
        if (b->b.physaddr && !test_bit(B_InoIdx, &b->b.flags))
                lafs_allocated_block(fs, &b->b, 0);
diff --git a/index.c b/index.c
index 3f6755834180275d69b435d2d1818274405f285c..bb1b80418445870214594cfca8e6d8be1f6a11ca 100644 (file)
--- a/index.c
+++ b/index.c
@@ -390,6 +390,7 @@ void lafs_phase_flip(struct fs *fs, struct block *b)
        BUG_ON(b->parent == NULL && !test_bit(B_Root, &b->flags));
        BUG_ON(ib->uninc_table.pending_cnt);
        BUG_ON(atomic_read(&ib->pincnt[oldphase]));
+       BUG_ON(!test_bit(B_IOLock, &b->flags));
 
        /* If this is the only reference, and pincnts are zero
         * and all relevant flags are clear, then don't flip
@@ -1655,6 +1656,7 @@ int lafs_allocated_block(struct fs *fs, struct block *blk, u64 phys)
        BUG_ON(!test_bit(B_Dirty, &blk->flags) &&
               !test_bit(B_Realloc, &blk->flags) &&
                phys != 0);
+       BUG_ON(!test_bit(B_IOLock, &blk->flags));
 
        if (test_bit(B_Root, &blk->flags)) {
                int i;
diff --git a/inode.c b/inode.c
index 948bac089ce955038a0ebfb7137cd30b0b207fb0..efa43326ecc81641bc2fa6bc0be7d33c9ee007e2 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -508,7 +508,9 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                } else {
                        BUG_ON(LAFSI(ino)->type != 0);
                        lafs_orphan_release(fs, b);
+                       lafs_iolock_block(&ib->b);
                        lafs_erase_iblock(ib);
+                       lafs_iounlock_block(&ib->b, 0);
                        lafs_erase_dblock(b);
                }
                putiref(ib, MKREF(inode_handle_orphan));
diff --git a/roll.c b/roll.c
index 02c4b0b846addd8e004d6fab0d74cead7087d199..4a39e387dad4b54417807c449a0409f6426b1535 100644 (file)
--- a/roll.c
+++ b/roll.c
@@ -446,10 +446,12 @@ roll_block(struct fs *fs, int fsnum, int inum, int trunc, int flg,
                lafs_pin_dblock(blk); /* cannot fail during ! ->rolled */
                lafs_dirty_dblock(blk);
 
+               lafs_iolock_block(&blk->b);
                if (lafs_allocated_block(fs, &blk->b, baddr))
                        printk("MALLOC ERROR\n"); /* FIXME */
                dprintk("Allocated block %lu to %llu\n",
                       (unsigned long)bnum, baddr);
+               lafs_iounlock_block(&blk->b, 0);
 
                clear_bit(B_PinPending, &blk->b.flags);
                clear_bit(B_Dirty, &blk->b.flags);