From cace3d99ae496c25673b5f3817ef53993194003a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 19 Sep 2010 14:23:18 +1000 Subject: [PATCH] Update youth during seg_apply_all If we added blocks to a segment is seg_apply_all, make sure the youth has been updated properly. Signed-off-by: NeilBrown --- segments.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/segments.c b/segments.c index 92c616a..346102b 100644 --- a/segments.c +++ b/segments.c @@ -403,7 +403,8 @@ void lafs_seg_move(struct fs *fs, u64 oldaddr, u64 newaddr, static void set_youth(struct fs *fs, struct segsum *ss) { u16 y; - u16 *youthp; + u16 *ybuf, *youthp; + int dirty = 0; /* HACK youth_next should always be at least 0x8000 so that * cleanable score differentiates well for new segments. @@ -421,13 +422,17 @@ static void set_youth(struct fs *fs, struct segsum *ss) )) /* Haven't decayed this block yet - revert decay */ y = decay_undo(y); - youthp = map_dblock(ss->youthblk); - youthp[ss->segnum & ((1 << (fs->blocksize_bits - - 1)) - 1)] - = cpu_to_le16(y); - fs->youth_next++; + ybuf = map_dblock(ss->youthblk); + youthp = ybuf + (ss->segnum & ((1 << (fs->blocksize_bits + - 1)) - 1)); + if (le16_to_cpu(*youthp) < 8) { + *youthp = cpu_to_le16(y); + fs->youth_next++; + dirty = 1; + } unmap_dblock(ss->youthblk, youthp); - lafs_dirty_dblock(ss->youthblk); + if (dirty) + lafs_dirty_dblock(ss->youthblk); } static void seg_apply(struct fs *fs, struct segsum *ss) @@ -441,6 +446,9 @@ static void seg_apply(struct fs *fs, struct segsum *ss) err = lafs_read_block(ss->ssblk); BUG_ON(err); // FIXME do something useful here seg_inc(fs, ss, diff, 1); + + if (diff > 0 && ss->youthblk) + set_youth(fs, ss); } /* lafs_seg_apply_all -- 2.39.5