Skip to contentSkip to conversation

md: Introduction - Assorted bugfixes

PATCH New NeilBrown 2 participants 7 messages Jan 23, 2007 – Jan 24, 2007 MD RAID

lore
Share & tools
lore

NeilBrown

author
#0 lore raw

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.

author
#1 lore raw

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
diff .prev/MAINTAINERS ./MAINTAINERS
@@ -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
author
#2 lore raw

PATCH 1/1 md: Make 'repair' actually work for raid1.

In reply to NeilBrown

When '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
diff .prev/drivers/md/raid1.c ./drivers/md/raid1.c
@@ -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);
+
 				}
 			}
 	}
#3 lore raw

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 ;)

author
#4 lore raw

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

author
#5 lore raw

PATCH 1/1 md: Make sure the events count in an md array never returns to zero.

In reply to NeilBrown

Now 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
diff .prev/drivers/md/md.c ./drivers/md/md.c
@@ -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 ... */
author
#6 lore raw

PATCH 1/1 md: Avoid reading past the end of a bitmap file.

In reply to NeilBrown

In 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.

Cc "yang yin" <[email protected]>

### Diffstat output

 ./drivers/md/bitmap.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/md/bitmap.c +8 -4
diff .prev/drivers/md/bitmap.c ./drivers/md/bitmap.c
@@ -479,9 +479,12 @@ static int bitmap_read_sb(struct bitmap 
 	int 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(struct 
 			int 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) {