From 824275a5d2d6f3b9641f90519e26b499a2ba2665 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 15 Sep 2010 13:58:39 +1000 Subject: [PATCH] Don't hold counted reference while on leafs list. 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 --- block.c | 4 ---- checkpoint.c | 12 ++++++++---- clean.c | 2 +- cluster.c | 10 +++------- index.c | 12 ++++-------- lafs.h | 3 +++ 6 files changed, 19 insertions(+), 24 deletions(-) diff --git a/block.c b/block.c index 21aecd6..c883c9c 100644 --- 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); diff --git a/checkpoint.c b/checkpoint.c index 93e5082..7eaa664 100644 --- a/checkpoint.c +++ b/checkpoint.c @@ -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 e85ae28..cf4bc1e 100644 --- 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); } diff --git a/cluster.c b/cluster.c index 1f317c1..dd29852 100644 --- 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 acff2fe..74fc533 100644 --- 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 504fdd8..082d67b 100644 --- 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); -- 2.39.5