]> git.neil.brown.name Git - LaFS.git/commitdiff
Revise dirty/valid rules for Index blocks.
authorNeilBrown <neilb@suse.de>
Mon, 24 Aug 2009 03:30:24 +0000 (13:30 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 24 Aug 2009 03:30:24 +0000 (13:30 +1000)
An Index block is 'Valid' if it contains any index.
So an InoIdx block for a depth=0 inode is never Valid
(as there is data rather than indexes there).

When it comes time to cluster_allocate an Index block,
if it is not Valid, we simple allocated_block it to 0.

An index block is Dirty if there are any children that need incorporation
as well was when incorporate has happened but has not yet been
written.
So an Index block can be Dirty but not Valid (unlike data blocks).

block.c
cluster.c
index.c
inode.c
modify.c

diff --git a/block.c b/block.c
index 9a387d08588c424bef45181a94c4dc47322b3a06..01b915993f3f6f2ecaf32b1d9713f5eefb948d06 100644 (file)
--- a/block.c
+++ b/block.c
@@ -566,47 +566,6 @@ lafs_erase_dblock(struct datablock *b)
        lafs_iounlock_block(&b->b, 0);
 }
 
-void
-lafs_erase_iblock(struct indexblock *b)
-{
-       struct fs *fs = fs_from_inode(b->b.inode);
-
-       LAFS_BUG(!test_bit(B_IOLock, &b->b.flags), &b->b);
-       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);
-
-       if (b->b.physaddr && !test_bit(B_InoIdx, &b->b.flags))
-               lafs_allocated_block(fs, &b->b, 0);
-       spin_lock(&fs->lock);
-       if (test_bit(B_Pinned, &b->b.flags)) {
-               /* We should only be erasing index blocks when
-                * they have no children.  We shouldn't be on
-                * a _leaf list because we hold IOLock
-                */
-               int onlist = 0;
-               LAFS_BUG(atomic_read(&b->pincnt[0]), &b->b);
-               LAFS_BUG(atomic_read(&b->pincnt[1]), &b->b);
-               if (!list_empty(&b->b.lru)) {
-                       list_del_init(&b->b.lru);
-                       onlist = 1;
-               }
-               if (!test_bit(B_Root, &b->b.flags))
-                       atomic_dec(&b->b.parent->pincnt
-                                  [!!test_bit(B_Phase1, &b->b.flags)]);
-               clear_bit(B_Pinned, &b->b.flags);
-               spin_unlock(&fs->lock);
-               lafs_inode_checkpin(b->b.inode);
-               if (!test_bit(B_Root, &b->b.flags))
-                       lafs_refile(&b->b.parent->b, 0);
-               if (onlist)
-                       putiref(b, MKREF(leaf));
-       } else
-               spin_unlock(&fs->lock);
-}
-
 void
 lafs_dirty_iblock(struct indexblock *b)
 {
@@ -620,7 +579,6 @@ lafs_dirty_iblock(struct indexblock *b)
         * in the previous phase.
         */
 
-       LAFS_BUG(!test_bit(B_Valid, &b->b.flags), &b->b);
        LAFS_BUG(!test_bit(B_Pinned, &b->b.flags), &b->b);
        if (!test_and_set_bit(B_Dirty, &b->b.flags)) {
                if (!test_and_clear_bit(B_Credit, &b->b.flags)) {
index b8778674b8259fea40d2cb8a16740c5714071643..50cebd1f03ae90b870944c35cdc3a8dc757f480d 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -480,6 +480,7 @@ static int flush_data_to_inode(struct block *b)
        }
        lai->depth = 0;
        lai->iblock->depth = 0;
+       clear_bit(B_Valid, &lai->iblock->b.flags);
 
        /* safe to reference ->dblock as b is a dirty child */
        db = getdref(lai->dblock, MKREF(flush2db));
@@ -524,6 +525,14 @@ unsigned long long lafs_cluster_allocate(struct block *b, int cnum)
        lai = LAFSI(b->inode);
 
        if (!test_bit(B_Valid, &b->flags)) {
+               if (test_bit(B_PhysValid, &b->flags) &&
+                   !test_bit(B_InoIdx, &b->flags) &&
+                   b->physaddr != 0)
+                       lafs_allocated_block(fs, b, 0);
+               if (test_and_clear_bit(B_Dirty, &b->flags))
+                       lafs_space_return(fs, 1);
+               if (test_and_clear_bit(B_Realloc, &b->flags))
+                       lafs_space_return(fs, 1);
                lafs_iounlock_block(b, B_IOLock);
                return wc->cluster_seq;
        }
diff --git a/index.c b/index.c
index 50cd7600ce483ca423cd9bfc34efff0e2da8960d..1a67f9944341391905ecf98bf8cb3f6960cd22c7 100644 (file)
--- a/index.c
+++ b/index.c
@@ -1033,7 +1033,8 @@ lafs_make_iblock(struct inode *ino, int adopt, int async, REFARG)
        if (test_bit(B_PhysValid, &lai->dblock->b.flags))
                set_bit(B_PhysValid, &new->b.flags);
        LAFS_BUG(!test_bit(B_Valid, &lai->dblock->b.flags), &lai->dblock->b);
-       set_bit(B_Valid, &new->b.flags);
+       if (lai->depth > 0)
+               set_bit(B_Valid, &new->b.flags);
        new->b.inode = ino;
        new->depth = lai->depth;
        /* Note: this doesn't get hashed until the index
diff --git a/inode.c b/inode.c
index 8bb86f059d101d08cb77b246ece3283505283f3e..14e4ffcf2b6c7119b7f8d3aacb508e8b18520d80 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -599,9 +599,10 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                } else {
                        LAFS_BUG(LAFSI(ino)->type != 0, &b->b);
                        lafs_orphan_release(fs, b);
-                       lafs_iolock_block(&ib->b);
-                       lafs_erase_iblock(ib);
-                       lafs_iounlock_block(&ib->b, 0);
+                       if (test_bit(B_Dirty, &ib->b.flags)) {
+                               lafs_iolock_block(&ib->b);
+                               lafs_cluster_allocate(&ib->b, 0);
+                       }
                        lafs_erase_dblock(b);
                        clear_bit(I_Deleting, &LAFSI(ino)->iflags);
                }
@@ -685,9 +686,6 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                 */
                getiref(ib2, MKREF(inode_handle_orphan2));
                lafs_iolock_block(&ib2->b);
-               /* call lafs_incorporate at least once to ensure
-                * that lafs_erase_iblock gets called
-                */
                do
                        lafs_incorporate(fs, ib2);
                while (ib2->uninc_table.pending_cnt || ib2->uninc);
@@ -740,8 +738,7 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                 * pinning */
                LAFSI(ino)->trunc_next = next_trunc;
                lafs_iolock_block(&ib->b);
-               lafs_erase_iblock(ib);
-               lafs_iounlock_block(&ib->b, 0);
+               lafs_cluster_allocate(&ib->b, 0);
                goto out;
        }
        
@@ -787,7 +784,7 @@ static int lafs_inode_handle_orphan(struct datablock *b)
                LAFS_BUG(!test_bit(B_PhysValid, &ib->b.flags), &ib->b);
                LAFS_BUG(ib->b.physaddr != 0, &ib->b);
        }
-       lafs_clear_index(ib);
+       clear_bit(B_Valid, &ib->b.flags);
 
  out:
        lafs_checkpoint_unlock(fs);
index c86df0f702edfa7d5816d70587d7d6ed40bc1bbd..87a167c847098dbec27542469ec07f53844fd858 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1323,8 +1323,6 @@ static int do_incorporate_leaf(struct fs *fs, struct indexblock *ib,
                share_list(&ib->uninc_next, &new->uninc_next, next);
        new->uninc_table.pending_cnt = 0;
        new->uninc_table.credits = 0;
-BUG_ON(!test_bit(B_Dirty, &new->b.flags) &&
-     !test_bit(B_Realloc, &new->b.flags));
        share_uninic(&ib->uninc_table, &new->uninc_table, next);
        spin_unlock(&fs->lock);
 
@@ -1508,6 +1506,11 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
 
        LAFS_BUG(!test_bit(B_IOLock, &ib->b.flags), &ib->b);
 
+       if (!test_bit(B_Valid, &ib->b.flags)) {
+               lafs_clear_index(ib);
+               set_bit(B_Valid, &ib->b.flags);
+       }
+
        if (ib->depth <= 1) {
                /* take a copy of the uninc_table so we can work while
                 * more changes can be made
@@ -1703,15 +1706,13 @@ void lafs_incorporate(struct fs *fs, struct indexblock *ib)
        }
        lafs_space_return(fs, uit.credits);
 
-       /* If this index block is now empty, we need to be sure it
-        * is erased.  But if there is anything pending in the next phase
-        * we need to wait for that to complete.
+       /* 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 (test_bit(B_Valid, &ib->b.flags) &&
-           lafs_leaf_next(ib, ib->b.fileaddr) == 0xFFFFFFFF &&
-           atomic_read(&ib->pincnt[0]) == 0 &&
-           atomic_read(&ib->pincnt[1]) == 0)
-               lafs_erase_iblock(ib);
+           lafs_leaf_next(ib, ib->b.fileaddr) == 0xFFFFFFFF)
+               clear_bit(B_Valid, &ib->b.flags);
 }
 
 /***************************************************************