]> git.neil.brown.name Git - LaFS.git/commitdiff
Factor out seg_add_new
authorNeilBrown <neilb@suse.de>
Sat, 18 Sep 2010 06:38:46 +0000 (16:38 +1000)
committerNeilBrown <neilb@suse.de>
Sat, 18 Sep 2010 06:38:46 +0000 (16:38 +1000)
We had multiple places that add entries to the segtracker.  Now we
only have one.

Signed-off-by: NeilBrown <neilb@suse.de>
segments.c

index 41dd6ec1a40654f7af7c2af349c058c87827f804..5690add179309b08625775b32f85be6bca523945 100644 (file)
@@ -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)