From 7571ae887d3b96d8e7ce63d43828866c6a91cdc6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 7 Oct 2010 11:54:46 +1100 Subject: md/raid1: avoid overflow in raid1 resync when bitmap is in use. bitmap_start_sync returns - via a pass-by-reference variable - the number of sectors before we need to check with the bitmap again. Since commit ef4256733506f245 this number can be substantially larger, 2^27 is a common value. Unfortunately it is an 'int' and so when raid1.c:sync_request shifts it 9 places to the left it becomes 0. This results in a zero-length read which the scsi layer justifiably complains about. This patch just removes the shift so the common case becomes safe with a trivially-correct patch. In the next merge window we will convert this 'int' to a 'sector_t' Reported-by: "George Spelvin" Signed-off-by: NeilBrown --- drivers/md/raid1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ad83a4dcadc3ed..fba4d2feaeb4ae 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1912,7 +1912,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) break; BUG_ON(sync_blocks < (PAGE_SIZE>>9)); - if (len > (sync_blocks<<9)) + if ((len >> 9) > sync_blocks) len = sync_blocks<<9; } -- cgit 1.2.3-korg From db8d9d3591f77cc6b66248b2cdfa1c43deee5ec9 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 7 Oct 2010 12:00:50 +1100 Subject: md/raid1: minor bio initialisation improvements. When performing a resync we pre-allocate some bios and repeatedly use them. This requires us to re-initialise them each time. One field (bi_comp_cpu) and some flags weren't being initiaised reliably. Signed-off-by: NeilBrown --- drivers/md/raid1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index fba4d2feaeb4ae..0b830bbe1d8b63 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1839,7 +1839,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* take from bio_init */ bio->bi_next = NULL; + bio->bi_flags &= ~(BIO_POOL_MASK-1); bio->bi_flags |= 1 << BIO_UPTODATE; + bio->bi_comp_cpu = -1; bio->bi_rw = READ; bio->bi_vcnt = 0; bio->bi_idx = 0; -- cgit 1.2.3-korg From 5c04f5512f8134c75cd36e5b0354e10e330f4e6e Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 1 Oct 2010 14:18:12 -0700 Subject: md: check return code of read_sb_page Function read_sb_page may return ERR_PTR(...). Check for it. Signed-off-by: Vasiliy Kulikov Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: NeilBrown --- drivers/md/bitmap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index ed4900ade93a4d..e4fb58db5454d4 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1000,10 +1000,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) page = bitmap->sb_page; offset = sizeof(bitmap_super_t); if (!file) - read_sb_page(bitmap->mddev, - bitmap->mddev->bitmap_info.offset, - page, - index, count); + page = read_sb_page( + bitmap->mddev, + bitmap->mddev->bitmap_info.offset, + page, + index, count); } else if (file) { page = read_page(file, index, bitmap, count); offset = 0; -- cgit 1.2.3-korg