static void finish_checkpoint(struct fs *fs, int youth)
{
+ /* Don't want to change the youth block while writing them out */
+ set_bit(DelayYouth, &fs->fsstate);
+
flush_accounting(fs);
/* if we are creating a snapshot, special handling is needed */
dprintk("FinalFlush %d\n", fs->seq);
lafs_cluster_flush(fs, 0);
+ clear_bit(DelayYouth, &fs->fsstate);
+
if (!test_bit(FinalCheckpoint, &fs->fsstate))
lafs_seg_apply_all(fs);
lafs_clean_free(fs);
fs->phase = 1;
fs->qphase = 0;
fs->checkpointing = CH_Checkpoint;
+ clear_bit(DelayYouth, &fs->fsstate);
first = fs->checkpointcluster;
err = roll_locate(fs, first, &next, &last, &seq, &max);
if (fs->qphase == fs->phase &&
fs->checkpointing) {
fs->checkpointing = 0;
+ clear_bit(DelayYouth, &fs->fsstate);
lafs_seg_apply_all(fs);
}
}
* FIXME there should be a more general way to delay
* updates to the Youth block.
*/
- if (!test_bit(FinalCheckpoint, &fs->fsstate) &&
+ if (!test_bit(DelayYouth, &fs->fsstate) &&
!(ssum &&
ssum->devnum == ss->dev &&
ssum->segnum == ss->segment)) {
if (fs->youth_next < 0x8000)
fs->youth_next = 0x8000;
- if (ssum && test_bit(FinalCheckpoint, &fs->fsstate)) {
+ if (ssum && test_bit(DelayYouth, &fs->fsstate)) {
ss_put(ssum, fs);
ssum = NULL;
}
#define CheckpointOpen 11 /* Some data has been written since the last checkpoint,
* so 'next_checkpoint' is a valid timestamp
*/
+#define DelayYouth 12 /* While set, don't update any youth blocks. The update will
+ * happen either during seg_apply_all or in roll-forward
+ */
unsigned long next_checkpoint; /* Valid when CheckpointOpen is set, holds
* jiffie time by when we need to do a checkpoint