From: NeilBrown Date: Thu, 1 Jul 2010 07:06:02 +0000 (+1000) Subject: cluster_reset X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=bd67d7f29af28095ffd66923793deefe5a6d4ecd;p=LaFS.git cluster_reset 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 --- diff --git a/cluster.c b/cluster.c index e3dbc64..01bef68 100644 --- 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);