]> git.neil.brown.name Git - LaFS.git/commitdiff
Make sure checkpoint happens after a timeout.
authorNeilBrown <neilb@suse.de>
Tue, 14 Sep 2010 01:10:25 +0000 (11:10 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 14 Sep 2010 01:10:25 +0000 (11:10 +1000)
If anything has been written since last check point, ensure another
checkpoint happens within 30 seconds.

This is partly to ensure that index block don't remain dirty forever.

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

index 32ab3452d49960e675450ef3fd089ff7e118135c..93e508279eb227311a778dae246444e74438ff08 100644 (file)
@@ -539,9 +539,18 @@ unsigned long lafs_do_checkpoint(struct fs *fs)
                if (fs->cleaner.active == 0 &&
                    fs->newsegments > fs->max_newsegs)
                        set_bit(CheckpointNeeded, &fs->fsstate);
+               else if (test_bit(CheckpointOpen, &fs->fsstate)) {
+                       unsigned long j = jiffies;
+                       if (time_after_eq(j, fs->next_checkpoint))
+                               set_bit(CheckpointNeeded, &fs->fsstate);
+                       else
+                               return fs->next_checkpoint - j;
+               } else
+                       return MAX_SCHEDULE_TIMEOUT;
        }
 
        if (!test_bit(CheckpointNeeded, &fs->fsstate))
+               /* Must have done final checkpoint */
                return MAX_SCHEDULE_TIMEOUT;
 
        if (fs->cleaner.active || ! fs->scan.done)
index e6633914d15e8c49f7e895c51a2fb7b751e1fe33..1f317c19e99935bab99425670ef1883d13d9f6c6 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -1140,6 +1140,14 @@ static void cluster_flush(struct fs *fs, int cnum)
        int vtype;
        int cluster_size;
 
+       if (!test_bit(CheckpointOpen, &fs->fsstate)) {
+               /* First cluster since a checkpoint, make sure
+                * we do another checkpoint within 30 seconds
+                */
+               fs->next_checkpoint = jiffies + 30 * HZ;
+               set_bit(CheckpointOpen, &fs->fsstate);
+               lafs_wake_thread(fs);
+       }
        /* set the writecluster size as this will guide layout in
         * some cases
         */
@@ -1212,9 +1220,10 @@ static void cluster_flush(struct fs *fs, int cnum)
                if (fs->checkpointing) {
                        spin_lock(&fs->lock);
                        wc->chead->flags = cpu_to_le32(fs->checkpointing);
-                       if (fs->checkpointing & CH_CheckpointEnd)
+                       if (fs->checkpointing & CH_CheckpointEnd) {
                                fs->checkpointing = 0;
-                       else if (fs->checkpointing & CH_CheckpointStart) {
+                               clear_bit(CheckpointOpen, &fs->fsstate);
+                       } else if (fs->checkpointing & CH_CheckpointStart) {
                                fs->checkpointcluster = head_addr[0];
                                fs->checkpointing &= ~CH_CheckpointStart;
                        }
diff --git a/index.c b/index.c
index 79bca851c574f57fac25c46acfea5d311eed699c..65d36c8f664c22e3f0b542027a24e24a7656dd15 100644 (file)
--- a/index.c
+++ b/index.c
@@ -97,9 +97,6 @@ static int lafs_shrinker(int nr_to_scan, /*gfp_t*/unsigned int gfp_mask)
                        list_del(&ib->b.lru);
                        lafs_iblock_free(ib);
                }
-               /* FIXME
-                * while (nr_to_scan) trigger some flushing
-                */
        }
        return freelist.freecnt;
 }
diff --git a/state.h b/state.h
index 589a56e044da3504b5b1da6643462c49f427d7c1..57bdddf9e0dcb7973dc952393328ed028ec4b09c 100644 (file)
--- a/state.h
+++ b/state.h
@@ -119,6 +119,13 @@ struct fs {
                             * should be after the next checkpoint unless that
                             * releases lots of space
                             */
+#define CheckpointOpen 11 /* Some data has been written since the last checkpoint,
+                          * so 'next_checkpoint' is a valid timestamp
+                          */
+
+       unsigned long next_checkpoint; /* Valid when CheckpointOpen is set, holds
+                                       * jiffie time by when we need to do a checkpoint
+                                       */
 
        struct work_struct done_work;   /* used for handling
                                         * refile after write completes */