From: Neil Brown We replace 'size' by 'start'. 'start' means exactly the same as 'curr_offset - size', and the equivalence of the new code can be tested based on this. The difference is that 'start' will never be negative and so can fit in a 'sector_t' while 'size' could be negative. Also make curr_offset sector_t, as it should have been. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/drivers/md/linear.c | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff -puN drivers/md/linear.c~md-fix-problem-with-unsigned-variable-going-negative-in-linearc drivers/md/linear.c --- 25/drivers/md/linear.c~md-fix-problem-with-unsigned-variable-going-negative-in-linearc 2004-11-13 17:38:01.174449656 -0800 +++ 25-akpm/drivers/md/linear.c 2004-11-13 17:38:01.179448896 -0800 @@ -117,8 +117,8 @@ static int linear_run (mddev_t *mddev) struct linear_hash *table; mdk_rdev_t *rdev; int i, nb_zone, cnt; - sector_t size; - unsigned int curr_offset; + sector_t start; + sector_t curr_offset; struct list_head *tmp; conf = kmalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t), @@ -193,23 +193,24 @@ static int linear_run (mddev_t *mddev) * Here we generate the linear hash table */ table = conf->hash_table; - size = 0; + start = 0; curr_offset = 0; for (i = 0; i < cnt; i++) { dev_info_t *disk = conf->disks + i; + if (start > curr_offset) + table[-1].dev1 = disk; + disk->offset = curr_offset; curr_offset += disk->size; - if (size < 0) { - table[-1].dev1 = disk; - } - size += disk->size; - - while (size>0) { + /* 'curr_offset' is the end of this disk + * 'start' is the start of table + */ + while (start < curr_offset) { table->dev0 = disk; table->dev1 = NULL; - size -= conf->smallest->size; + start += conf->smallest->size; table++; } } _