From: NeilBrown Date: Sat, 18 Sep 2010 13:00:48 +0000 (+1000) Subject: Introduce DelayYouth X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=b2a029bea69d62257dce059da9cd74e43a814a88;p=LaFS.git Introduce DelayYouth When writing out the accounting blocks we need to not update the youth block if we happen to start a new segment. We already do that at unmount time, so generalise it with a new flag. Signed-Off-By: NeilBrown --- diff --git a/checkpoint.c b/checkpoint.c index 4701938..c031506 100644 --- a/checkpoint.c +++ b/checkpoint.c @@ -488,6 +488,9 @@ static void flush_accounting(struct fs *fs) 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 */ @@ -502,6 +505,8 @@ static void finish_checkpoint(struct fs *fs, int youth) 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); diff --git a/roll.c b/roll.c index c75b1b4..e9a20fa 100644 --- a/roll.c +++ b/roll.c @@ -484,6 +484,7 @@ static int roll_forward(struct fs *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); @@ -522,6 +523,7 @@ static int roll_forward(struct fs *fs) if (fs->qphase == fs->phase && fs->checkpointing) { fs->checkpointing = 0; + clear_bit(DelayYouth, &fs->fsstate); lafs_seg_apply_all(fs); } } diff --git a/segments.c b/segments.c index 847c144..12a6453 100644 --- a/segments.c +++ b/segments.c @@ -1089,7 +1089,7 @@ again: * 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)) { @@ -1116,7 +1116,7 @@ again: 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; } diff --git a/state.h b/state.h index 0bc3cba..78f3deb 100644 --- a/state.h +++ b/state.h @@ -122,6 +122,9 @@ struct fs { #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