From ced4e3a8b59a00fb8e3e92aead4d2b7bd483ff01 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 29 Jun 2010 21:57:33 +1000 Subject: [PATCH] Properly track segrefs held by active segments. Each active segment holds a segref. This is currently in a slightly haphazard way. If .dev is >= 0 a segref is held, so new_segment drops it, then devs .dev to -1, unless a new segment is found. Signed-off-by: NeilBrown --- cluster.c | 13 ++++++++++--- super.c | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cluster.c b/cluster.c index 04f5930..330738a 100644 --- a/cluster.c +++ b/cluster.c @@ -263,8 +263,9 @@ static int seg_remainder(struct fs *fs, struct segpos *seg) * this segment */ struct fs_dev *dv = &fs->devs[seg->dev]; - int rows = dv->rows_per_table - seg->st_row; + + BUG_ON(seg->dev < 0); rows += dv->rows_per_table * (dv->tables_per_seg - seg->st_table - 1); return rows * dv->width; } @@ -290,6 +291,7 @@ static u32 seg_setsize(struct fs *fs, struct segpos *seg, u32 size) */ struct fs_dev *dv = &fs->devs[seg->dev]; u32 rv; + BUG_ON(seg->dev < 0); size = (size + dv->width - 1) / dv->width; rv = size * dv->width; size += seg->st_row; @@ -385,8 +387,13 @@ static int new_segment(struct fs *fs, int cnum) */ if (wc->seg.dev >= 0) { p = segtovirt(fs, wc->seg.dev, wc->seg.num); - lafs_seg_deref(fs, p, 0); + /* If this is the first segment, p would be 0, + * so add one to ensure we drop the reference. + */ + lafs_seg_deref(fs, p + 1, 0); + wc->seg.dev = -1; } + wc->remaining = 0; if (cnum && fs->clean_reserved < fs->max_segment) @@ -395,7 +402,7 @@ static int new_segment(struct fs *fs, int cnum) lafs_free_get(fs, &dev, &seg, 0); wc->seg.dev = dev; wc->seg.num = seg; - seg_setpos(fs, &wc->seg, (p = segtovirt(fs, dev, seg))); + seg_setpos(fs, &wc->seg, segtovirt(fs, dev, seg)); wc->remaining = seg_remainder(fs, &wc->seg); return 0; diff --git a/super.c b/super.c index 80699b4..71f5098 100644 --- a/super.c +++ b/super.c @@ -549,6 +549,7 @@ lafs_load(struct options *op, int newest) INIT_LIST_HEAD(&fs->wc[i].pending_blocks[j]); } init_waitqueue_head(&fs->wc[i].pending_wait); + fs->wc[i].seg.dev = -1; } fs->max_newblocks = 1000; /* FIXME this should be configurable, and -- 2.39.5