* again and remove it properly so it can become cleanable later.
*/
+#define SCORE_MAX 0xFFFFFFFC /* Maximum normal score */
+#define SCORE_ACTIVE 0xFFFFFFFD /* This segment is being written to */
+#define SCORE_CLEANING 0xFFFFFFFE /* This segment in being cleaned */
+#define SCORE_DEAD 0xFFFFFFFF /* This segment is to be removed */
+
struct segstat {
u16 next;
u16 dev;
static void segdelete_all(struct segtracker *st, struct fs *fs)
{
- /* walk entire skip list. Any entry with score of 0xFFFFFFFF
+ /* walk entire skip list. Any entry with score of SCORE_DEAD
* is deleted
*/
u16 *where[SEG_NUM_HEIGHTS];
while (*where[0] != 0xFFFF) {
u16 pos = *where[0];
struct segstat *ss = segfollow(st, pos);
- if (ss->score == 0xFFFFFFFF) {
+ if (ss->score == SCORE_DEAD) {
/* delete this entry */
/* Locking is really bad here */
if (fs->segtrack->free.first == 0xFFFF)
fs->segtrack->free.last = 0xFFFF;
fs->segtrack->free.cnt--;
- ss->score = 0xFFFFFFFD;
+ ss->score = SCORE_ACTIVE;
/* still in table, but unlinked */
spin_unlock(&fs->lock);
* the clean list. If cleanable, set score to 0 to make
* sure it is found soon
*/
- if (ss->score == 0xFFFFFFFE) {
+ if (ss->score == SCORE_CLEANING) {
ss->next = fs->segtrack->clean.first;
fs->segtrack->clean.first = where[0][0];
if (fs->segtrack->clean.last == 0xFFFF)
fs->segtrack->clean.last =
fs->segtrack->clean.first;
fs->segtrack->clean.cnt++;
- } else if (ss->score != 0xFFFFFFFD) {
+ }
+ if (ss->score != SCORE_ACTIVE) {
+ /* Must be on the clean list now */
ss->score = 0;
ss->usage = 0;
}
dprintk("SEG: cleanable %d/%d score=%d usage=%d\n",
ss->dev, ss->segment, ss->score, ss->usage);
+ ss->score = SCORE_CLEANING;
if (ss->usage == 0) {
int rv;
- ss->score = 0xFFFFFFFE;
spin_unlock(&fs->lock);
rv = add_clean(fs, ss->dev, ss->segment);
/* FIXME we dropped the lock, so maybe this could bug?? */
score = youth * usage / segsize + 0x10000;
spin_lock(&fs->lock);
+ if (score > SCORE_MAX)
+ score = SCORE_MAX;
ss = segfind(fs->segtrack, dev, seg, where);
if (ss) {
/* already in the table. Just update the usage.
* It must be on the right list.
*/
- if (ss->score == 0xFFFFFFFD)
+ if (ss->score == SCORE_ACTIVE)
; /* still in use */
- if (ss->usage == 0 && ss->score > 0)
+ else if (ss->usage == 0 && ss->score > 0)
; /* on free list, leave it alone */
else {
ss->usage = usage;
fs->segtrack->cleanable.cnt = keep;
ss = segfollow(fs->segtrack, ssnum);
while (ss) {
- ss->score = 0xFFFFFFFF;
+ ss->score = SCORE_DEAD;
ss = segfollow(fs->segtrack, ss->next);
}
segdelete_all(fs->segtrack, fs);
fs->segtrack->cleanable.cnt = 0;
while (ssnum != 0xffff) {
ss = segfollow(fs->segtrack, ssnum);
- ss->score = 0xFFFFFFFF;
+ ss->score = SCORE_DEAD;
ssnum = ss->next;
}
fs->segtrack->clean.cnt = 0;
while (ssnum != 0xffff) {
ss = segfollow(fs->segtrack, ssnum);
- ss->score = 0xFFFFFFFF;
+ ss->score = SCORE_DEAD;
ssnum = ss->next;
}
fs->segtrack->free.cnt = 0;
while (ssnum != 0xffff) {
ss = segfollow(fs->segtrack, ssnum);
- ss->score = 0xFFFFFFFF;
+ ss->score = SCORE_DEAD;
ssnum = ss->next;
}