]> git.neil.brown.name Git - LaFS.git/commitdiff
Don't hold counted reference while on leafs list.
authorNeilBrown <neilb@suse.de>
Wed, 15 Sep 2010 03:58:39 +0000 (13:58 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 15 Sep 2010 03:58:39 +0000 (13:58 +1000)
Doing so makes the refcount calculations in lafs_refile messy.

We don't drop a block while it is dirty etc anyway so there is no loss

Signed-off-by: NeilBrown <neilb@suse.de>
block.c
checkpoint.c
clean.c
cluster.c
index.c
lafs.h

diff --git a/block.c b/block.c
index 21aecd6d500bda4cfcb1ab37001223930dc03fbf..c883c9cff1a0061fd87de48ae2cd3741c0096e6d 100644 (file)
--- a/block.c
+++ b/block.c
@@ -575,10 +575,8 @@ erase_dblock_locked(struct datablock *b)
                 * leaf list, so we must remove it.
                 * However it is IOLocked so it might not be on the leaf list.
                 */
-               int onlru = 0;
                LAFS_BUG(test_bit(B_Writeback, &b->b.flags), &b->b);
                if (!list_empty(&b->b.lru)) {
-                       onlru = 1;
                        list_del_init(&b->b.lru);
                }
                if (!test_bit(B_Root, &b->b.flags))
@@ -588,8 +586,6 @@ erase_dblock_locked(struct datablock *b)
                spin_unlock(&fs->lock);
                if (!test_bit(B_Root, &b->b.flags))
                        lafs_refile(&b->b.parent->b, 0);
-               if (onlru)
-                       putiref(b, MKREF(leaf));
        } else
                spin_unlock(&fs->lock);
 
index 93e508279eb227311a778dae246444e74438ff08..7eaa664e344908421b3f3f3596b45524e0ac89c8 100644 (file)
@@ -340,9 +340,13 @@ retry:
        else
                b = NULL;
 
-       if (b)
-               /* the list counted a reference.  Now we hold it */
+       if (b) {
+               if (test_bit(B_InoIdx, &b->flags))
+                       getiref_locked(iblk(b), MKREF(flushable));
+               else
+                       getref_locked(b, MKREF(flushable));
                list_del_init(&b->lru);
+       }
        spin_unlock(&fs->lock);
        if (!b)
                return b;
@@ -354,7 +358,7 @@ retry:
 
        if (!lafs_is_leaf(b, phase)) {
                lafs_iounlock_block(b);
-               putref(b, MKREF(leaf));
+               putref(b, MKREF(flushable));
                goto retry;
        }
 
@@ -440,7 +444,7 @@ again:
                if (unlock)
                        lafs_iounlock_block(b);
 
-               putref(b, MKREF(leaf));
+               putref(b, MKREF(flushable));
        }
        if ((test_bit(B_Pinned, &LAFSI(fs->ss[0].root)->iblock->b.flags) &&
             !!test_bit(B_Phase1, &LAFSI(fs->ss[0].root)->iblock->b.flags)
diff --git a/clean.c b/clean.c
index e85ae28e70038115d19964f908f31ace47e59ca3..cf4bc1e123fe6f5de18cf96c051e0f5a622cb607 100644 (file)
--- a/clean.c
+++ b/clean.c
@@ -139,7 +139,7 @@ static void cleaner_flush(struct fs *fs)
                }
                if (unlock)
                        lafs_iounlock_block(b);
-               putref(b, MKREF(leaf));
+               putref(b, MKREF(flushable));
        }
        lafs_cluster_flush(fs, 1);
 }
index 1f317c19e99935bab99425670ef1883d13d9f6c6..dd29852df4d9f51a00d9197760c07aee7751ab03 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -757,18 +757,14 @@ int lafs_cluster_allocate(struct block *b, int cnum)
        if (!list_empty_careful(&b->lru)) {
                /* Someone is flushing this block before
                 * checkpoint got to it - probably writepage.
-                * Must remove it from the leaf lru
+                * Must remove it from the leaf lru so it can go
+                * on the cluster list.
                 */
-               int onlru = 1;
                LAFS_BUG(test_bit(B_OnFree, &b->flags), b);
                spin_lock(&fs->lock);
-               if (list_empty(&b->lru))
-                       onlru = 0;
-               else
+               if (!list_empty(&b->lru))
                        list_del_init(&b->lru);
                spin_unlock(&fs->lock);
-               if (onlru)
-                       putref(b, MKREF(leaf));
        }
 
        if (test_and_set_bit(B_Writeback, &b->flags))
diff --git a/index.c b/index.c
index acff2fe8067edf10c00cb6b2c0c867a061f02439..74fc5337127a0f2225faf1bec8bd2280d6913a61 100644 (file)
--- a/index.c
+++ b/index.c
@@ -246,6 +246,8 @@ struct indexblock *getiref_locked(struct indexblock *ib, REFARG)
                ok = 1;
        if (spin_is_locked(&lafs_hash_lock))
                ok = 1;
+       if (spin_is_locked(&fs_from_inode(ib->b.inode)->lock))
+               ok = 1;
        LAFS_BUG(!ok, &ib->b);
 
        if (!test_bit(B_InoIdx, &ib->b.flags)) {
@@ -859,7 +861,6 @@ static void set_lru(struct block *b)
                else
                        list_add(&b->lru, &fs->phase_leafs[ph]);
 
-               getref(b, MKREF(leaf));
        }
        spin_unlock(&fs->lock);
        /* allow lafs_iolock_block-empty to complete */
@@ -906,7 +907,7 @@ void lafs_refile(struct block *b, int dec)
                /* PinPending disappears with the last non-lru reference,
                 * (or possibly at other times).
                 */
-               if (atomic_read(&b->refcnt) == dec + onlru)
+               if (atomic_read(&b->refcnt) == dec)
                        clear_bit(B_PinPending, &b->flags);
 
                ph = !!test_bit(B_Phase1, &b->flags);
@@ -921,7 +922,7 @@ void lafs_refile(struct block *b, int dec)
                     (iblk(b)->uninc_table.pending_cnt == 0 &&
                      iblk(b)->uninc == NULL &&
                      iblk(b)->uninc_next == NULL &&
-                     atomic_read(&b->refcnt) == dec+onlru &&
+                     atomic_read(&b->refcnt) == dec &&
                      atomic_read(&iblk(b)->pincnt[0]) == 0 &&
                      atomic_read(&iblk(b)->pincnt[1]) == 0))
                        ) {
@@ -930,12 +931,7 @@ void lafs_refile(struct block *b, int dec)
                        if (test_and_clear_bit(B_Pinned, &b->flags)) {
                                if (onlru) {
                                        spin_lock(&fs->lock);
-                                       del_ref(b, MKREF(leaf), __FILE__,__LINE__);
                                        list_del_init(&b->lru);
-                                       if (dec)
-                                               atomic_dec(&b->refcnt);
-                                       else
-                                               dec = onlru;
                                        spin_unlock(&fs->lock);
                                }
                                if (test_bit(B_InoIdx, &b->flags) &&
diff --git a/lafs.h b/lafs.h
index 504fdd8fa9d5309746fc97266105a9b8e35505ed..082d67b4a4094c47c30f3c4af6401eea8dec1fd3 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -470,6 +470,9 @@ static inline struct block *_getref_locked(struct block *b)
        if (test_bit(B_Dirty, &b->flags) || test_bit(B_Realloc, &b->flags))
                if (spin_is_locked(&fs_from_inode(b->inode)->lock))
                        ok = 1;
+       if(spin_is_locked(&fs_from_inode(b->inode)->lock))
+               /* Removing from leaf list */
+               ok = 1;
        if (!ok)
                printk("Not locked: %s\n", strblk(b));
        BUG_ON(!ok);