]> git.neil.brown.name Git - LaFS.git/commitdiff
More issues with wc->seg being explicitly unset at certain times.
authorNeilBrown <neilb@suse.de>
Thu, 1 Jul 2010 07:13:47 +0000 (17:13 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 2 Jul 2010 23:31:19 +0000 (09:31 +1000)
We need to clear wc->seg at the end of a cleaning segment when we
choose not to add another, and we need to cope correctly when such
a segment is found.

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

index 01bef6888efa462af102091f10e384e04609a3d3..3bbe200d2b9c6b37d1513bbd8c9d2e7594ba92f9 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -362,8 +362,13 @@ static u64 seg_addr(struct fs *fs, struct segpos *seg)
         * the block stepped over. FIXME this comment is wrong.
         */
        struct fs_dev *dv = &fs->devs[seg->dev];
+       u64 addr;
 
-       u64 addr = seg->col * dv->stride;
+       if (seg->dev < 0)
+               /* Setting 'next' address for last cluster in
+                * a cleaner segment */
+               return 0;
+       addr = seg->col * dv->stride;
        addr += seg->row;
        addr += seg->table * (dv->stride);  /* FIXME */
        addr += seg->num * dv->segment_stride;
@@ -414,8 +419,8 @@ static int new_segment(struct fs *fs, int cnum)
                wc->seg.dev = -1;
        }
 
-       if (cnum &&
-           fs->clean_reserved < fs->max_segment)
+       if (cnum < 0 ||
+           (cnum && fs->clean_reserved < fs->max_segment))
                        return -ENOSPC;
        /* This gets a reference on the 'segsum' */
        lafs_free_get(fs, &dev, &seg, 0);
@@ -789,7 +794,7 @@ int lafs_cluster_allocate(struct block *b, int cnum)
                        avail = 1;
                else
                        avail = 0;
-               if (wc->remaining < 1)
+               if (wc->seg.dev < 0 || wc->remaining < 1)
                        used = -1;
                else
                        used = cluster_insert(&wc->slhead, &wc->clhead, b, avail);
@@ -1190,8 +1195,12 @@ static void cluster_flush(struct fs *fs, int cnum)
        /* Need to make sure out ->next_addr gets set properly
         * for non-cleaning segments
         */
-       if (wc->remaining < 2 && cnum == 0)
-               new_segment(fs, cnum);
+       if (wc->remaining < 2) {
+               if (cnum == 0)
+                       new_segment(fs, cnum);
+               else
+                       new_segment(fs, -1);
+       }
 
        /* Fill in the cluster header */
        strncpy(wc->chead->idtag, "LaFSHead", 8);