From f46d078379e5cffc7d3de8fac408fc2ac905191e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 18 Sep 2010 16:38:46 +1000 Subject: [PATCH] Factor out seg_add_new We had multiple places that add entries to the segtracker. Now we only have one. Signed-off-by: NeilBrown --- segments.c | 138 ++++++++++++++++++++++++----------------------------- 1 file changed, 63 insertions(+), 75 deletions(-) diff --git a/segments.c b/segments.c index 41dd6ec..5690add 100644 --- a/segments.c +++ b/segments.c @@ -1034,7 +1034,7 @@ static void segdelete_all(struct segtracker *st, struct fs *fs) if (ss->score == SCORE_DEAD) { /* delete this entry */ - /* Locking is really bad here */ + /* FIXME Locking is really bad here */ struct segsum *ssm; ssm = segsum_find(fs, ss->segment, ss->dev, 0); putdref(ssm->ssblk, MKREF(intable)); @@ -1220,6 +1220,47 @@ static u16 segunused(struct segtracker *st) return rv; } +static struct segstat *seg_add_new(struct segtracker *st, struct slist *which, int atend, + int dev, u32 seg, int score, int usage, + u16 *where[SEG_NUM_HEIGHTS]) +{ + int ssn; + struct segstat *ss; + + ssn = segunused(st); + ss = segfollow(st, ssn); + if (!ss) + return ss; + + if (which) { + if (atend) { + int l = which->last; + ss->next = 0xFFFF; + if (l == 0xFFFF) { + which->first = ssn; + which->last = ssn; + } else { + which->last = ssn; + BUG_ON(segfollow(st, l)->next != 0xFFFF); + segfollow(st, l)->next = ssn; + } + } else { + ss->next = which->first; + which->first = ssn; + if (which->last == 0xFFFF) + which->last = ssn; + } + which->cnt++; + } + ss->dev = dev; + ss->segment = seg; + ss->score = score; + ss->usage = usage; + seginsert(st, ssn, where); + lafs_check_seg_cnt(st); + return ss; +} + int lafs_clean_count(struct fs *fs, int *any_clean) { int rv; @@ -1235,7 +1276,6 @@ static int add_free(struct fs *fs, unsigned int dev, u32 seg, u16 *youthp) /* This dev/seg is known to be free. add it to the list */ struct segstat *ss; u16 *where[SEG_NUM_HEIGHTS]; - int ssn; dprintk("add_free %d %d\n", (int)dev, (int)seg); spin_lock(&fs->lock); if (*youthp) { @@ -1259,21 +1299,10 @@ static int add_free(struct fs *fs, unsigned int dev, u32 seg, u16 *youthp) spin_unlock(&fs->lock); return 0; } - ssn = segunused(fs->segtrack); - ss = segfollow(fs->segtrack, ssn); - if (ss) { - ss->next = fs->segtrack->free.first; - fs->segtrack->free.first = ssn; - if (fs->segtrack->free.last == 0xFFFF) - fs->segtrack->free.last = ssn; - fs->segtrack->free.cnt++; - ss->dev = dev; - ss->segment = seg; - ss->score = 0; - ss->usage = 0; - seginsert(fs->segtrack, ssn, where); - lafs_check_seg_cnt(fs->segtrack); - } + + seg_add_new(fs->segtrack, &fs->segtrack->free, 0, + dev, seg, 0, 0, where); + spin_unlock(&fs->lock); return 1; } @@ -1288,7 +1317,6 @@ static int add_clean(struct fs *fs, unsigned int dev, u32 seg) */ struct segstat *ss; u16 *where[SEG_NUM_HEIGHTS]; - int ssn; dprintk("ADD CLEAN %d/%d %d #####################################\n", dev, seg, fs->segtrack->clean.cnt); @@ -1323,22 +1351,9 @@ static int add_clean(struct fs *fs, unsigned int dev, u32 seg) return 0; } - ssn = segunused(fs->segtrack); - ss = segfollow(fs->segtrack, ssn); - if (ss) { - ss->next = fs->segtrack->clean.first; - fs->segtrack->clean.first = ssn; - if (fs->segtrack->clean.last == 0xFFFF) - fs->segtrack->clean.last = - fs->segtrack->clean.first; - fs->segtrack->clean.cnt++; - ss->dev = dev; - ss->segment = seg; - ss->score = 0; - ss->usage = 0; - seginsert(fs->segtrack, ssn, where); - lafs_check_seg_cnt(fs->segtrack); - } + ss = seg_add_new(fs->segtrack, &fs->segtrack->clean, 0, + dev, seg, 0, 0, where); + spin_unlock(&fs->lock); if (ss) return 1; @@ -1354,7 +1369,6 @@ void lafs_add_active(struct fs *fs, u64 addr) * via free_get */ struct segstat *ss; - int ssn; u16 *where[SEG_NUM_HEIGHTS]; struct segsum *ssum = segsum_byaddr(fs, addr, 0); (void)getdref(ssum->ssblk, MKREF(intable)); @@ -1362,17 +1376,11 @@ void lafs_add_active(struct fs *fs, u64 addr) spin_lock(&fs->lock); ss = segfind(fs->segtrack, ssum->devnum, ssum->segnum, where); BUG_ON(ss); - ssn = segunused(fs->segtrack); - ss = segfollow(fs->segtrack, ssn); + ss = seg_add_new(fs->segtrack, NULL, 0, + ssum->devnum, ssum->segnum, + SCORE_ACTIVE, 0, where); BUG_ON(!ss); - ss->dev = ssum->devnum; - ss->segment = ssum->segnum; - ss->score = SCORE_ACTIVE; - ss->usage = 0; - seginsert(fs->segtrack, ssn, where); - lafs_check_seg_cnt(fs->segtrack); - spin_unlock(&fs->lock); } @@ -1526,7 +1534,7 @@ retry: st->max_score = segfollow(st, st->cleanable.last)->score; } - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); ss = segfollow(st, st->cleanable.first); st->cleanable.first = ss->next; @@ -1580,11 +1588,10 @@ static int add_cleanable(struct fs *fs, unsigned int dev, u32 seg, { u32 score; struct segstat *ss; - int ssn; u32 segsize; u16 *where[SEG_NUM_HEIGHTS]; - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); if (fs->scan.trace || lafs_trace || 1) printk("CLEANABLE: %u/%lu y=%d u=%d\n", dev, (unsigned long)seg, (int)youth, (int)usage); @@ -1598,7 +1605,7 @@ static int add_cleanable(struct fs *fs, unsigned int dev, u32 seg, if (usage == 0) { int rv = add_clean(fs, dev, seg); - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); return rv; } @@ -1626,8 +1633,8 @@ static int add_cleanable(struct fs *fs, unsigned int dev, u32 seg, ss->usage = usage; ss->score = score; } + lafs_check_seg_cnt(fs->segtrack); spin_unlock(&fs->lock); - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); return 0; } @@ -1663,33 +1670,14 @@ static int add_cleanable(struct fs *fs, unsigned int dev, u32 seg, if (fs->segtrack->max_score && fs->segtrack->max_score < score) { /* score too high to bother with */ + lafs_check_seg_cnt(fs->segtrack); spin_unlock(&fs->lock); - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); return 0; } - ssn = segunused(fs->segtrack); - ss = segfollow(fs->segtrack, ssn); - if (ss) { - int l = fs->segtrack->cleanable.last; - ss->next = 0xFFFF; - if (l == 0xFFFF) { - fs->segtrack->cleanable.first = ssn; - fs->segtrack->cleanable.last = ssn; - } else { - fs->segtrack->cleanable.last = ssn; - BUG_ON(segfollow(fs->segtrack, l)->next != 0xFFFF); - segfollow(fs->segtrack, l)->next = ssn; - } - fs->segtrack->cleanable.cnt++; - ss->dev = dev; - ss->segment = seg; - ss->score = score; - ss->usage = usage; - seginsert(fs->segtrack, ssn, where); - } + seg_add_new(fs->segtrack, &fs->segtrack->cleanable, 1, + dev, seg, score, usage, where); spin_unlock(&fs->lock); - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); return 1; } @@ -1837,7 +1825,7 @@ unsigned long lafs_scan_seg(struct fs *fs) return 1; fs->scan.free_stage = 1; } - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); if (fs->scan.free_stage == 1) { /* Find the main usage block and copy the data into * our temp block @@ -1913,7 +1901,7 @@ unsigned long lafs_scan_seg(struct fs *fs) fs->scan.usage0_db = db; fs->scan.free_stage = 2; } - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); while (fs->scan.free_stage > 1 && fs->scan.free_stage < fs->maxsnapshot + 1) { struct datablock *db; @@ -1957,7 +1945,7 @@ unsigned long lafs_scan_seg(struct fs *fs) fs->scan.free_stage++; putdref(db, MKREF(usage_ss)); - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); } if (fs->scan.free_stage == fs->maxsnapshot + 1) { /* All usage data has been merged, we can record all these @@ -1990,7 +1978,7 @@ unsigned long lafs_scan_seg(struct fs *fs) fs->scan.usage0_db = NULL; fs->scan.free_stage = 0; } - WARN_ON(lafs_check_seg_cnt(fs->segtrack)); + lafs_check_seg_cnt(fs->segtrack); if (fs->scan.trace) return HZ/10; else if (fs->scan.free_stage == 0) -- 2.39.5