]> git.neil.brown.name Git - LaFS.git/commitdiff
rollforward: use segpos functions to walk the addresses in the write cluster.
authorNeilBrown <neilb@suse.de>
Mon, 18 Oct 2010 00:32:02 +0000 (11:32 +1100)
committerNeilBrown <neilb@suse.de>
Mon, 18 Oct 2010 01:29:08 +0000 (12:29 +1100)
This ensures we get the right addresses in a 2-D striped layout.

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

index c06b3a245e0f7fbc41d5216a31e6228fb8017b27..5e188ce6231f093e0ee5dc2e73f92e63bb10ca2e 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -284,7 +284,7 @@ static void seg_step(struct fs *fs, struct segpos *seg)
        seg->col = 0;
 }
 
-static u32 seg_setsize(struct fs *fs, struct segpos *seg, u32 size)
+u32 lafs_seg_setsize(struct fs *fs, struct segpos *seg, u32 size)
 {
        /* move the 'nxt' table/row to be 'size' blocks beyond
         * current start. size will be rounded up to a multiple
@@ -301,7 +301,7 @@ static u32 seg_setsize(struct fs *fs, struct segpos *seg, u32 size)
        return rv;
 }
 
-static void seg_setpos(struct fs *fs, struct segpos *seg, u64 addr)
+void lafs_seg_setpos(struct fs *fs, struct segpos *seg, u64 addr)
 {
        /* set seg to start at the given virtual address, and be
         * of size 0
@@ -348,7 +348,7 @@ static u64 seg_addr(struct fs *fs, struct segpos *seg)
        return addr;
 }
 
-static u64 seg_next(struct fs *fs, struct segpos *seg)
+u64 lafs_seg_next(struct fs *fs, struct segpos *seg)
 {
        /* step forward one block, returning the address of
         * the block stepped over
@@ -435,7 +435,7 @@ static int new_segment(struct fs *fs, int cnum)
        }
        /* This gets a reference on the 'segsum' */
        lafs_free_get(fs, &dev, &seg, 0);
-       seg_setpos(fs, &wc->seg, segtovirt(fs, dev, seg));
+       lafs_seg_setpos(fs, &wc->seg, segtovirt(fs, dev, seg));
        BUG_ON(wc->seg.dev != dev);
        BUG_ON(wc->seg.num != seg);
 
@@ -1149,12 +1149,13 @@ static void cluster_flush(struct fs *fs, int cnum)
        else
                clear_bit(SecondFlushNeeded, &fs->fsstate);
 
-       cluster_size = seg_setsize(fs, &wc->seg,
-                                  seg_remainder(fs, &wc->seg) - wc->remaining);
+       cluster_size = lafs_seg_setsize(fs, &wc->seg,
+                                       seg_remainder(fs, &wc->seg)
+                                       - wc->remaining);
 
        /* find, and step over, address header block(s) */
        for (i = 0; i < wc->chead_blocks ; i++)
-               head_addr[i] = seg_next(fs, &wc->seg);
+               head_addr[i] = lafs_seg_next(fs, &wc->seg);
 
        list_for_each_entry(b, &wc->clhead, lru) {
                u64 addr;
@@ -1174,7 +1175,7 @@ static void cluster_flush(struct fs *fs, int cnum)
                } else
                        current_block++;
                cluster_incdesc(wc, desc_start, b, fs->blocksize_bits);
-               addr = seg_next(fs, &wc->seg);
+               addr = lafs_seg_next(fs, &wc->seg);
                if (cnum && test_bit(B_Dirty, &b->flags))
                        /* We are cleaning but this block is now dirty.
                         * Don't waste the UnincCredit on recording the
@@ -1528,7 +1529,7 @@ int lafs_cluster_init(struct fs *fs, int cnum, u64 addr, u64 prev, u64 seq)
        wc->cnum = cnum;
 
        if (addr) {
-               seg_setpos(fs, &wc->seg, addr);
+               lafs_seg_setpos(fs, &wc->seg, addr);
                cluster_reset(fs, wc);
                BUG_ON(cnum);
                spin_lock(&fs->lock);
diff --git a/lafs.h b/lafs.h
index 37cd4a18f9625c32f8d283815fdceeb84c857b06..7af975fabdbf677f6cdc38ac494ddf542a111d73 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -767,6 +767,9 @@ int lafs_cluster_init(struct fs *fs, int cnum, u64 addr, u64 prev, u64 seq);
 void lafs_clusters_done(struct fs *fs);
 void lafs_done_work(struct work_struct *ws);
 void lafs_close_all_segments(struct fs *fs);
+u32 lafs_seg_setsize(struct fs *fs, struct segpos *seg, u32 size);
+void lafs_seg_setpos(struct fs *fs, struct segpos *seg, u64 addr);
+u64 lafs_seg_next(struct fs *fs, struct segpos *seg);
 
 /* index.c */
 void lafs_pin_block_ph(struct block *b, int ph);
diff --git a/roll.c b/roll.c
index 5b741ee38d780072e4a05fe5c137a1b24c24c2ff..1649be311f0fe4689e97dae7812c4a781d5d1ba0 100644 (file)
--- a/roll.c
+++ b/roll.c
@@ -511,9 +511,11 @@ roll_one(struct fs *fs, u64 *addrp, struct page *p, struct page *pg,
        struct group_head *gh;
        struct descriptor *desc;
        int i;
-       u64 baddr = addr;
+       u64 baddr;
        int err;
        int blocksize = fs->blocksize;
+       struct segpos seg;
+       int header_blocks;
 
        /* we "know" buf is big enough */
        err = lafs_load_page(fs, p, addr, max/blocksize);
@@ -530,7 +532,13 @@ roll_one(struct fs *fs, u64 *addrp, struct page *p, struct page *pg,
        if (le16_to_cpu(ch->Hlength) > max)
                return -EIO;
 
-       baddr += (le16_to_cpu(ch->Hlength) + blocksize - 1) / blocksize;
+       lafs_seg_setpos(fs, &seg, addr);
+       lafs_seg_setsize(fs, &seg, le16_to_cpu(ch->Clength));
+       header_blocks = (le16_to_cpu(ch->Hlength) + blocksize - 1) / blocksize;
+       for (i = 0; i < header_blocks; i++) {
+               baddr = lafs_seg_next(fs, &seg);
+               BUG_ON(baddr != addr + i);
+       }
 
        if (!(ch->flags & CH_Checkpoint))
                fs->qphase = fs->phase;
@@ -569,9 +577,8 @@ roll_one(struct fs *fs, u64 *addrp, struct page *p, struct page *pg,
                                                                 pg);
                                        bnum++;
                                        if (bytes != DescHole)
-                                               baddr++;
+                                               baddr = lafs_seg_next(fs, &seg);
                                }
-                               /* FIXME allow for striping */
                                desc++;
                        } else {
                                struct miniblock *mb = (struct miniblock *)desc;