From: Evan Felix <evan.felix@pnl.gov>

Here is a patch that fixes a major issue in the raid5/6 code.  It seems
that the code:

logical_sector = bi->bi_sector & ~(STRIPE_SECTORS-1);
(sector_t)     = (sector_t)    & (constant)

that the right side of the & does not get extended correctly when the
constant is promoted to the sector_t type.  I have CONFIG_LBD turned on so
sector_t should be 64bits wide.  This fails to properly mask the value of
4294967296 (2TB/512) to 4294967296.  in my case it was coming out 0.  this
cause the loop following this code to read from 0 to 4294967296 blocks so
it could write one character.

As you might imagine this makes a format of a 3.5TB filesystem take a very
long time.


---

 25-power4-akpm/drivers/md/raid5.c     |    3 +--
 25-power4-akpm/drivers/md/raid6main.c |    2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff -puN drivers/md/raid5.c~raid56-masking-fix drivers/md/raid5.c
--- 25-power4/drivers/md/raid5.c~raid56-masking-fix	2004-04-07 15:10:39.037782032 -0700
+++ 25-power4-akpm/drivers/md/raid5.c	2004-04-07 15:11:39.510588768 -0700
@@ -1358,9 +1358,8 @@ static int make_request (request_queue_t
 		disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bi));
 	}
 
-	logical_sector = bi->bi_sector & ~(STRIPE_SECTORS-1);
+	logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
 	last_sector = bi->bi_sector + (bi->bi_size>>9);
-
 	bi->bi_next = NULL;
 	bi->bi_phys_segments = 1;	/* over-loaded to count active stripes */
 	if ( bio_data_dir(bi) == WRITE )
diff -puN drivers/md/raid6main.c~raid56-masking-fix drivers/md/raid6main.c
--- 25-power4/drivers/md/raid6main.c~raid56-masking-fix	2004-04-07 15:10:39.039781728 -0700
+++ 25-power4-akpm/drivers/md/raid6main.c	2004-04-07 15:10:39.044780968 -0700
@@ -1521,7 +1521,7 @@ static int make_request (request_queue_t
 		disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bi));
 	}
 
-	logical_sector = bi->bi_sector & ~(STRIPE_SECTORS-1);
+	logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
 	last_sector = bi->bi_sector + (bi->bi_size>>9);
 
 	bi->bi_next = NULL;

_