md: Introduction - Assorted bugfixes
PATCH 1/1 md: Introduction - Assorted bugfixes
Following are 4 patches suitable for inclusion in 2.6.20.
Thanks,
NeilBrown
[PATCH 001 of 4] md: Update email address and status for MD in MAINTAINERS. [PATCH 002 of 4] md: Make 'repair' actually work for raid1.
[PATCH 003 of 4] md: Make sure the events count in an md array never returns to zero. [PATCH 004 of 4] md: Avoid reading past the end of a bitmap file.
PATCH 1/1 md: Update email address and status for MD in MAINTAINERS.
### Diffstat output
./MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
MAINTAINERS +2 -2
@@ -3011,9 +3011,9 @@ SOFTWARE RAID (Multiple Disks) SUPPORT P: Ingo Molnar M: [email protected] P: Neil Brown -M: [email protected] +M: [email protected] L: [email protected] -S: Maintained +S: Supported SOFTWARE SUSPEND: P: Pavel Machek
PATCH 1/1 md: Make 'repair' actually work for raid1.
In reply to NeilBrownWhen 'repair' finds a block that is different one the various parts of the mirror. it is meant to write a chosen good version to the others. However it currently writes out the original data to each. The memcpy to make all the data the same is missing.
### Diffstat output
./drivers/md/raid1.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/md/raid1.c +5 -0
@@ -1221,6 +1221,11 @@ static void sync_request_write(mddev_t * sbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; sbio->bi_bdev = conf->mirrors[i].rdev->bdev; +for (j =0 ; j < vcnt ; j++) +memcpy (page_address (sbio->bi_io_vec[j].bv_page), +page_address (pbio->bi_io_vec[j].bv_page), +PAGE_SIZE ); + } } }
Re: [PATCH 002 of 4] md: Make 'repair' actually work for raid1.
drivers/md/raid1.c static void sync_request_write(mddev_t * · line 1227
Quoted 4 lines · On Tue, 23 Jan 2007 11:26:52 +1100 NeilBrown <[email protected]> wrote:
drivers/md/raid1.c +4
-0+for (j =0 ; j < vcnt ; j++) +memcpy (page_address (sbio->bi_io_vec[j].bv_page), +page_address (pbio->bi_io_vec[j].bv_page), +PAGE_SIZE );
I trust these BIOs are known to only contain suitably-allocated, MD-private pages? Because if these pages can be user pages then this change is spectacularly buggy ;)
Re: [PATCH 002 of 4] md: Make 'repair' actually work for raid1.
Quoted 11 lines · On Tuesday January 23, [email protected] wrote:
drivers/md/raid1.c static void sync_request_write(mddev_t * · line 1227
Quoted 4 lines · On Tue, 23 Jan 2007 11:26:52 +1100 NeilBrown <[email protected]> wrote:
drivers/md/raid1.c +4
-0+for (j =0 ; j < vcnt ; j++) +memcpy (page_address (sbio->bi_io_vec[j].bv_page), +page_address (pbio->bi_io_vec[j].bv_page), +PAGE_SIZE );I trust these BIOs are known to only contain suitably-allocated, MD-private pages? Because if these pages can be user pages then this change is spectacularly buggy ;)
Your trust is well placed.
This is in the 'resync' path, were all buffers are allocated in lowmem and are full pages and so-forth, so this is perfectly safe.
NeilBrown
PATCH 1/1 md: Make sure the events count in an md array never returns to zero.
In reply to NeilBrownNow that we sometimes step the array events count backwards (when transitioning dirty->clean where nothing else interesting has happened - so that we don't need to write to spares all the time), it is possible for the event count to return to zero, which is potentially confusing and triggers and MD_BUG.
We could possibly remove the MD_BUG, but is just as easy, and probably safer, to make sure we never return to zero.
### Diffstat output
./drivers/md/md.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/md.c +2 -1
@@ -1633,7 +1633,8 @@ repeat:* and 'events' is odd, we can roll back to the previous clean state */ if (nospares && (mddev->in_sync && mddev->recovery_cp == MaxSector) - && (mddev->events &1 )) + && (mddev->events &1 ) + && mddev->events !=1 ) mddev->events--;else {/* otherwise we have to go forward and ... */
PATCH 1/1 md: Avoid reading past the end of a bitmap file.
In reply to NeilBrownIn most cases we check the size of the bitmap file before reading data from it. However when reading the superblock, we always read the first PAGE_SIZE bytes, which might not always be appropriate. So limit that read to the size of the file if appropriate.
Also, we get the count of available bytes wrong in one place, so that too can read past the end of the file.
### Diffstat output
./drivers/md/bitmap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/md/bitmap.c +8 -4
@@ -479,9 +479,12 @@ static int bitmap_read_sb(struct bitmapint err = -EINVAL ;/* page 0 is the superblock, read it... */ -if (bitmap->file) - bitmap->sb_page =read_page (bitmap->file,0 , bitmap,PAGE_SIZE ); -else { +if (bitmap->file) { +loff_t isize =i_size_read (bitmap->file->f_mapping->host); +int bytes = isize >PAGE_SIZE ?PAGE_SIZE : isize; + + bitmap->sb_page =read_page (bitmap->file,0 , bitmap, bytes); + }else { bitmap->sb_page =read_sb_page (bitmap->mddev, bitmap->offset,0 ); }if (IS_ERR (bitmap->sb_page)) {
@@ -877,7 +880,8 @@ static int bitmap_init_from_disk(structint count;/* unmap the old page, we're done with it */ if (index == num_pages-1 ) - count = bytes - index *PAGE_SIZE ; + count = bytes +sizeof (bitmap_super_t) + - index *PAGE_SIZE ;else count =PAGE_SIZE ;if (index ==0 ) {