From d5587982e6e599fef2b2c6254aa1a097bff4192b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 18 Oct 2010 11:32:02 +1100 Subject: [PATCH] rollforward: use segpos functions to walk the addresses in the write cluster. This ensures we get the right addresses in a 2-D striped layout. Signed-off-by: NeilBrown --- cluster.c | 19 ++++++++++--------- lafs.h | 3 +++ roll.c | 15 +++++++++++---- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cluster.c b/cluster.c index c06b3a2..5e188ce 100644 --- 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 37cd4a1..7af975f 100644 --- 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 5b741ee..1649be3 100644 --- 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; -- 2.39.5