From: Neil Brown <neilb@cse.unsw.edu.au>

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 <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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++;
 		}
 	}
_