]> git.neil.brown.name Git - LaFS.git/commitdiff
Use a new flag to identify blocks being processed by the cleaner.
authorNeilBrown <neilb@suse.de>
Sat, 14 Aug 2010 05:01:34 +0000 (15:01 +1000)
committerNeilBrown <neilb@suse.de>
Sat, 14 Aug 2010 07:58:20 +0000 (17:58 +1000)
This will help future patch which will unify cleaning and orphans
list_heads, and make is clear when a refcount is being help.

Signed-off-by: NeilBrown <neilb@suse.de>
clean.c
state.h

diff --git a/clean.c b/clean.c
index 806f9cf6ef60f61aa86e43c830e0d3201189893a..aff7c95efd4cdea6499ea87f7a35dedd6c9dcd1e 100644 (file)
--- a/clean.c
+++ b/clean.c
@@ -291,11 +291,13 @@ static int try_clean(struct fs *fs, struct toclean *tc)
                        if (b == NULL)
                                break;
 
-                       if (list_empty(&b->cleaning)) {
-                               list_add_tail(&b->cleaning, &tc->cleaning);
+                       if (!test_and_set_bit(B_Cleaning, &b->b.flags)) {
                                getdref(b, MKREF(cleaning));
                                igrab(ino);
                        }
+                       if (list_empty(&b->cleaning))
+                               list_add_tail(&b->cleaning, &tc->cleaning);
+
                        /* FIXME do I need a memory barrier. to ensure truncate
                         * sees the not-list_empty, and we see i_size? */
 
@@ -304,8 +306,10 @@ static int try_clean(struct fs *fs, struct toclean *tc)
                             ((loff_t)bnum << ino->i_blkbits)
                             >= i_size_read(ino))) {
                                list_del_init(&b->cleaning);
-                               putdref(b, MKREF(cleaning));
-                               iput(ino);
+                               if (test_and_clear_bit(B_Cleaning, &b->b.flags)) {
+                                       putdref(b, MKREF(cleaning));
+                                       iput(ino);
+                               }
                        }
                        putdref(b, MKREF(cleaning));
                }
@@ -361,10 +365,12 @@ static int try_clean(struct fs *fs, struct toclean *tc)
                 */
        done_cleaning:
                list_del_init(&b->cleaning);
-               ino = b->b.inode;
-               putdref(b, MKREF(cleaning));
+               if (test_and_clear_bit(B_Cleaning, &b->b.flags)) {
+                       ino = b->b.inode;
+                       putdref(b, MKREF(cleaning));
+                       iput(ino);
+               }
                putref(cb, MKREF(clean2));
-               iput(ino);
                if (rv)
                        goto out;
        }
@@ -380,8 +386,9 @@ void lafs_unclean(struct datablock *db)
        if (!list_empty_careful(&db->cleaning)) {
                struct fs *fs = fs_from_inode(db->b.inode);
                mutex_lock(&fs->cleaner.lock);
-               if (!list_empty(&db->cleaning)) {
+               if (!list_empty(&db->cleaning))
                        list_del_init(&db->cleaning);
+               if (test_and_clear_bit(B_Cleaning, &db->b.flags)) {
                        putdref(db, MKREF(cleaning));
                        iput(db->b.inode);
                        if (test_and_clear_bit(B_Async, &db->b.flags)) {
diff --git a/state.h b/state.h
index 0c10615d8f57331b9e4c118cbdc32f2f0db52ce0..01b03d398b3ec75d19d80219ec54f083ad67de41 100644 (file)
--- a/state.h
+++ b/state.h
@@ -433,7 +433,7 @@ struct indexblock {
 #define dblk(__bl) container_of(__bl, struct datablock, b)
 
 enum {
-       /* NOTE: 31 flags in used.  Need to overlap 'data' with 'index' if
+       /* NOTE: 32 flags in used.  Need to overlap 'data' with 'index' if
         * we need much more
         */
        /* First flags that are meaningful for both Data and Index blocks
@@ -472,7 +472,7 @@ enum {
        B_PhysValid,    /* ->physaddr is correct */
 
        /* Flags that are only relevant for Data Block
-        * currently 6 */
+        * currently 7 */
 
        B_PinPending,    /* set on data blocks while checkpoint_locked if we might
                           * want to mark them dirty
@@ -487,8 +487,11 @@ enum {
        B_HaveWriteback,/* We own the page writeback flag and when all blocks
                         * are unlocked we should clear it. */
        B_Claimed,      /* Used for exclusive allocation of inodes */
+       B_Cleaning,     /* Used by cleaner to track which blocks it has a
+                        * reference on already. */
+
        /* Flags that are only relevant for Index Blocks
-        * currently 2 */
+        * currently 3 */
        B_OnFree,       /* index block on the free list */
        B_PrimaryRef,   /* This indexblock has not been incorporated into the
                         * parent, and so can only be found by being a sibling