From: NeilBrown Date: Fri, 18 Jun 2010 11:15:25 +0000 (+1000) Subject: segments: fix array sizes. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=6cd79ffdbf6907ab3c096a9b7ca63e49ca8d38da;p=LaFS.git segments: fix array sizes. Heights range from 0 up, so the array must be sized one larger than that maximum height. So defined SEG_NUM_HEIGHTS instead of SEG_MAX_HEIGHT, and make it one more. Signed-off-by: NeilBrown --- diff --git a/segments.c b/segments.c index 401e2ea..a941d69 100644 --- a/segments.c +++ b/segments.c @@ -702,7 +702,7 @@ int lafs_segtrack_init(struct segtracker *st) st->size[1] = 1; st->size[2] = 5; st->size[3] = 9; - BUG_ON(9 > SEG_MAX_HEIGHT); + BUG_ON(SEG_NUM_HEIGHTS <= 9); st->unused.first = st->unused.last = 0xffff; st->cleanable.first = st->cleanable.last = 0xffff; @@ -710,7 +710,7 @@ int lafs_segtrack_init(struct segtracker *st) st->clean.first = st->clean.last = 0xffff; st->unused.cnt = st->free.cnt = st->cleanable.cnt = 0; - for (h = 0; h < SEG_MAX_HEIGHT; h++) + for (h = 0; h < SEG_NUM_HEIGHTS; h++) st->head[h] = 0xFFFF; /* how many entries in each page */ @@ -888,14 +888,14 @@ static int statcmp(struct segstat *ss, u16 dev, u32 seg) } static struct segstat *segfind(struct segtracker *st, u16 dev, - u32 segnum, u16 *where[SEG_MAX_HEIGHT]) + u32 segnum, u16 *where[SEG_NUM_HEIGHTS]) { /* Find the segment entry for dev/segnum. * Return link info in where to allow insertion/deletion. */ int level; u16 *head = st->head; - for (level = SEG_MAX_HEIGHT-1 ; level >= 0; level--) { + for (level = SEG_NUM_HEIGHTS-1 ; level >= 0; level--) { while (head[level] != 0xffff && statcmp(segfollow(st, head[level]), dev, segnum) < 0) { head = segfollow(st, head[level])->skip; @@ -911,7 +911,7 @@ static struct segstat *segfind(struct segtracker *st, u16 dev, static int segchoose_height(struct segtracker *st, u16 ssn) { - unsigned long rand[DIV_ROUND_UP(SEG_MAX_HEIGHT * 2 / 8 + 1, + unsigned long rand[DIV_ROUND_UP(SEG_NUM_HEIGHTS * 2 / 8 + 1, sizeof(unsigned long))]; int max = st->size[ssn>>12]; int h = 0; @@ -928,7 +928,7 @@ static int segchoose_height(struct segtracker *st, u16 ssn) } static void seginsert(struct segtracker *st, u16 ssn, - u16 *where[SEG_MAX_HEIGHT]) + u16 *where[SEG_NUM_HEIGHTS]) { /* We looked for 'ss' but didn't find it. 'where' is the * result of looking. Now insert 'ss' @@ -947,7 +947,7 @@ static void segdelete(struct segtracker *st, struct segstat *ss) /* This segstat has just been removed from a list (free or cleanable). * Remove it from the skiplist as well */ - u16 *where[SEG_MAX_HEIGHT]; + u16 *where[SEG_NUM_HEIGHTS]; struct segstat *ss2 = segfind(st, ss->dev, ss->segment, where); int h; int pos; @@ -955,7 +955,7 @@ static void segdelete(struct segtracker *st, struct segstat *ss) BUG_ON(ss2 != ss); pos = *where[0]; - for (h = 0; h < SEG_MAX_HEIGHT && *where[h] == pos ; h++) + for (h = 0; h < SEG_NUM_HEIGHTS && *where[h] == pos ; h++) *where[h] = ss->skip[h]; ss->next = st->unused.first; st->unused.first = pos; @@ -969,10 +969,10 @@ static void segdelete_all(struct segtracker *st, struct fs *fs) /* walk entire skip list. Any entry with score of 0xFFFFFFFF * is deleted */ - u16 *where[SEG_MAX_HEIGHT]; + u16 *where[SEG_NUM_HEIGHTS]; int h; - for (h = SEG_MAX_HEIGHT-1; h >= 0; h--) + for (h = SEG_NUM_HEIGHTS-1; h >= 0; h--) where[h] = &st->head[h]; while (*where[0] != 0xFFFF) { @@ -988,7 +988,7 @@ static void segdelete_all(struct segtracker *st, struct fs *fs) putdref(ssm->youthblk, MKREF(intable)); ss_put(ssm, fs); - for (h = 0; h < SEG_MAX_HEIGHT && *where[h] == pos; h++) + for (h = 0; h < SEG_NUM_HEIGHTS && *where[h] == pos; h++) *where[h] = ss->skip[h]; ss->next = st->unused.first; st->unused.first = pos; @@ -996,7 +996,7 @@ static void segdelete_all(struct segtracker *st, struct fs *fs) lafs_check_seg_cnt(st); } else { /* advance 'where' to here */ - for (h = 0; h < SEG_MAX_HEIGHT && *where[h] == pos; h++) + for (h = 0; h < SEG_NUM_HEIGHTS && *where[h] == pos; h++) where[h] = &ss->skip[h]; } } @@ -1115,7 +1115,7 @@ static int add_free(struct fs *fs, unsigned int dev, u32 seg, u16 *youthp) { /* This dev/seg is known to be free. add it to the list */ struct segstat *ss; - u16 *where[SEG_MAX_HEIGHT]; + u16 *where[SEG_NUM_HEIGHTS]; int ssn; //printk("add_free %d %d\n", (int)dev, (int)seg); spin_lock(&fs->lock); @@ -1168,7 +1168,7 @@ static int add_clean(struct fs *fs, unsigned int dev, u32 seg) * implies a reference count). */ struct segstat *ss; - u16 *where[SEG_MAX_HEIGHT]; + u16 *where[SEG_NUM_HEIGHTS]; int ssn; dprintk("ADD CLEAN %d/%d %d #####################################\n", @@ -1426,7 +1426,7 @@ static int add_cleanable(struct fs *fs, unsigned int dev, u32 seg, struct segstat *ss; int ssn; u32 segsize; - u16 *where[SEG_MAX_HEIGHT]; + u16 *where[SEG_NUM_HEIGHTS]; WARN_ON(lafs_check_seg_cnt(fs->segtrack)); if (fs->scan.trace || lafs_trace) diff --git a/state.h b/state.h index b6f64c1..1e789e0 100644 --- a/state.h +++ b/state.h @@ -151,7 +151,8 @@ struct fs { int youth_block; /* block number of next block to decay */ int checkpoint_youth; // FIXME make sure this gets decayed -#define SEG_MAX_HEIGHT (9) +/* 10 heights: 0 to 9 */ +#define SEG_NUM_HEIGHTS (10) struct segtracker { void *page[4]; int size[4]; /* entry size in page as "number of skip pointers" */ @@ -159,7 +160,7 @@ struct fs { unsigned short first, last; unsigned short cnt; } unused, free, cleanable, clean; - unsigned short head[SEG_MAX_HEIGHT]; /* head of skiplist */ + unsigned short head[SEG_NUM_HEIGHTS]; /* head of skiplist */ int total; int max_score; int sorted_size;