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));
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;
/* 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) {
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;
}
*/
struct segstat *ss;
u16 *where[SEG_NUM_HEIGHTS];
- int ssn;
dprintk("ADD CLEAN %d/%d %d #####################################\n",
dev, seg, fs->segtrack->clean.cnt);
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;
* 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));
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);
}
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;
{
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);
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;
}
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;
}
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;
}
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
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;
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
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)