]> git.neil.brown.name Git - LaFS.git/commitdiff
lafs_refile: group all functionality that requires refcnt==0
authorNeilBrown <neilb@suse.de>
Wed, 15 Sep 2010 05:19:50 +0000 (15:19 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 15 Sep 2010 05:19:50 +0000 (15:19 +1000)
There are multiple silly (racy) tests on refcnt==dec.  Combine all
these tests into a single 'if' which is run only when the refcnt
reaches zero.

This patch just changes the code without fixing the indentation.  That
makes it easier to review.

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

diff --git a/index.c b/index.c
index ebef16781d4f293963a6b307448ccb4a6d9ca51c..a3e0afdb010a478762bcd0135201b166a9fe426e 100644 (file)
--- a/index.c
+++ b/index.c
@@ -890,6 +890,7 @@ void lafs_refile(struct block *b, int dec)
                int free_me = 0;
                struct inode *checkpin = NULL;
                struct inode *myi = NULL;
+               struct datablock *db;
 
                set_lru(b);
 
@@ -923,12 +924,13 @@ void lafs_refile(struct block *b, int dec)
                        lafs_checkpoint_unlock(fs);
                }
 
-               spin_lock(&lafs_hash_lock);
 
+
+               if (dec && _putref_norefile(b)) {
+               spin_lock(&lafs_hash_lock);
                /* PinPending disappears with the last non-lru reference,
                 * (or possibly at other times).
                 */
-               if (atomic_read(&b->refcnt) == dec)
                        clear_bit(B_PinPending, &b->flags);
 
                ph = !!test_bit(B_Phase1, &b->flags);
@@ -938,7 +940,6 @@ void lafs_refile(struct block *b, int dec)
                    !test_bit(B_PinPending, &b->flags) &&
                    !test_bit(B_Dirty, &b->flags) &&
                    !test_bit(B_Realloc, &b->flags) &&
-                   atomic_read(&b->refcnt) == dec &&
                    (!test_bit(B_Index, &b->flags) ||
                     (iblk(b)->uninc_table.pending_cnt == 0 &&
                      iblk(b)->uninc == NULL &&
@@ -975,7 +976,6 @@ void lafs_refile(struct block *b, int dec)
                }
 
                /* check the ->parent link */
-               if (atomic_read(&b->refcnt) == dec) {
                        if (b->parent &&
                            !(b->flags & (
                                      (1<<B_Pinned) |
@@ -1063,17 +1063,13 @@ void lafs_refile(struct block *b, int dec)
                                }
                                freelist.freecnt++;
                        }
-               }
-
-               if (dec) {
-                       if (_putref_norefile(b)) {
                                /* last reference to a dblock with no page
                                 * requires special handling
                                 * The first block on a page must be freed,
                                 * the other blocks hold a reference on that
                                 * first block which must be dropped.
                                 */
-                               struct datablock *db = dblk(b);
+                               db = dblk(b);
                                if (!test_bit(B_Index, &b->flags) &&
                                    !PagePrivate(db->page)) {
                                        int bits = (PAGE_SHIFT -
@@ -1106,12 +1102,9 @@ void lafs_refile(struct block *b, int dec)
                                        spin_unlock(&b->inode->i_data
                                                    .private_lock);
                                }
-                       }
-               }
 
                /* Free a delayed-release inode */
-               if (atomic_read(&b->refcnt) == 0 &&
-                   !test_bit(B_Index, &b->flags) &&
+               if (!test_bit(B_Index, &b->flags) &&
                    (myi = rcu_my_inode(dblk(b))) != NULL &&
                    (!PagePrivate(dblk(b)->page) ||
                     test_bit(I_Destroyed, &LAFSI(myi)->iflags))) {
@@ -1123,6 +1116,7 @@ void lafs_refile(struct block *b, int dec)
                                lafs_destroy_inode(myi);
                } else
                        spin_unlock(&lafs_hash_lock);
+               }
                rcu_iput(myi);
 
                if (physref) {