]> git.neil.brown.name Git - LaFS.git/commitdiff
cluster_reset
authorNeilBrown <neilb@suse.de>
Thu, 1 Jul 2010 07:06:02 +0000 (17:06 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 2 Jul 2010 23:31:19 +0000 (09:31 +1000)
split some common code into cluster_reset which should be
called after a flushing a cluster or after setting up a
new segment.

This wasn't really happening at all in one case.

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

index e3dbc6446f4206f92976e157ee1f6b1125e40796..01bef6888efa462af102091f10e384e04609a3d3 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -371,6 +371,26 @@ static u64 seg_addr(struct fs *fs, struct segpos *seg)
        return addr;
 }
 
+static void cluster_reset(struct fs *fs, struct wc *wc)
+{
+       int blocksize = fs->prime_sb->s_blocksize;
+       if (wc->seg.dev < 0) {
+               wc->remaining = 0;
+               wc->chead = NULL;
+               wc->chead_size = 0;
+               return;
+       }
+       wc->remaining = seg_remainder(fs, &wc->seg);
+       wc->chead_blocks = 1;
+       wc->remaining--;
+       wc->cluster_space = blocksize - sizeof(struct cluster_head);
+       wc->chead_size = sizeof(struct cluster_head);
+
+       wc->pending_next = (wc->pending_next+1) % 4;
+       wc->chead = page_address(wc->page[wc->pending_next]);
+       
+}
+
 static int new_segment(struct fs *fs, int cnum)
 {
        /* new_segment can fail if cnum > 0 and there is no
@@ -393,18 +413,16 @@ static int new_segment(struct fs *fs, int cnum)
                lafs_seg_deref(fs, p + 1, 0);
                wc->seg.dev = -1;
        }
-       wc->remaining = 0;
 
        if (cnum &&
            fs->clean_reserved < fs->max_segment)
                        return -ENOSPC;
        /* This gets a reference on the 'segsum' */
        lafs_free_get(fs, &dev, &seg, 0);
-       wc->seg.dev = dev;
-       wc->seg.num = seg;
        seg_setpos(fs, &wc->seg, segtovirt(fs, dev, seg));
+       BUG_ON(wc->seg.dev != dev);
+       BUG_ON(wc->seg.num != seg);
 
-       wc->remaining = seg_remainder(fs, &wc->seg);
        return 0;
 }
 
@@ -793,6 +811,7 @@ int lafs_cluster_allocate(struct block *b, int cnum)
                                mutex_unlock(&wc->lock);
                                return -ENOSPC;
                        }
+                       cluster_reset(fs, wc);
                }
        }
 
@@ -1340,13 +1359,7 @@ static void cluster_flush(struct fs *fs, int cnum)
        dprintk("D %d\n", wake);
 
        /* now re-initialise the cluster information */
-       wc->chead_blocks = 1;
-       wc->remaining--;
-       wc->cluster_space = sb->s_blocksize - sizeof(struct cluster_head);
-       wc->chead_size = sizeof(struct cluster_head);
-
-       wc->pending_next = (wc->pending_next+1) % 4;
-       wc->chead = page_address(wc->page[wc->pending_next]);
+       cluster_reset(fs, wc);
 
        wait_event(wc->pending_wait,
                   atomic_read(&wc->pending_cnt[wc->pending_next]) == 0);
@@ -1492,7 +1505,6 @@ bio_end_io_t *lafs_cluster_endio_choose(int which, int header)
 
 int lafs_cluster_init(struct fs *fs, int cnum, u64 addr, u64 prev, u64 seq)
 {
-       int blocksize = fs->prime_sb->s_blocksize;
        struct wc *wc = &fs->wc[cnum];
        int i;
 
@@ -1511,22 +1523,14 @@ int lafs_cluster_init(struct fs *fs, int cnum, u64 addr, u64 prev, u64 seq)
                }
                return -ENOMEM;
        }
-       wc->pending_next = 0;
-       wc->chead = page_address(wc->page[wc->pending_next]);
-
-       wc->chead_blocks = 1;
-       wc->cluster_space = blocksize - sizeof(struct cluster_head);
-       wc->chead_size = sizeof(struct cluster_head);
-
+       wc->pending_next = -1;
        wc->cluster_seq = seq;
        wc->prev_addr = prev;
-       seg_setpos(fs, &wc->seg, addr);
-       if (cnum)
-               wc->remaining = 0;
-       else
-               wc->remaining = seg_remainder(fs, &wc->seg) - 1;/*1 for header*/
-       if (prev && cnum == 0) {
-               /* if prev == 0 this is a brand new segment for cleaning */
+
+       if (addr) {
+               seg_setpos(fs, &wc->seg, addr);
+               cluster_reset(fs, wc);
+               BUG_ON(cnum);
                spin_lock(&fs->lock);
                fs->free_blocks += wc->remaining+1;
                spin_unlock(&fs->lock);