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)
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
*/
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;
}
list_del(&ib->b.lru);
lafs_iblock_free(ib);
}
- /* FIXME
- * while (nr_to_scan) trigger some flushing
- */
}
return freelist.freecnt;
}
* 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 */