Linux RAID subsystem development
 help / color / mirror / Atom feed
* [PATCH md 000 of 4] Introduction
@ 2005-05-10  5:04 NeilBrown
  2005-05-10  5:04 ` [PATCH md 003 of 4] Two small fixes for md verion-1 superblocks NeilBrown
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: NeilBrown @ 2005-05-10  5:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid

Hi Andrew,

Following are 4 patches for md in 2.6.12-rc3-mm3

The first is appropriate for 2.6.12 - it fixes a potential data corruption 
with linear arrays (which was notice under XFS which does journal writes with
interesting alignments I think).
The second fixes an unlikely-to-hit-in-real-life bug where if an array fails
to be assembled properly, an oops maybe could eventuate.

The last two relate to bitmap intent logging and so depend on the other 
related patches in -mm.
I think this bitmap stuff should be ready to go to Linus as soon as 2.6.12 is out.

Thanks,
NeilBrown

 [PATCH md 001 of 4] Fix spliting of md/linear request that cross a device boundary
 [PATCH md 002 of 4] Set the unplug_fn and issue_flush_fn for md devices *after* committed to creation.
 [PATCH md 003 of 4] Two small fixes for md verion-1 superblocks.
 [PATCH md 004 of 4] Make sure md/bitmap doesn't try to write a page with active writeback

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH md 001 of 4] Fix spliting of md/linear request that cross a device boundary
  2005-05-10  5:04 [PATCH md 000 of 4] Introduction NeilBrown
                   ` (2 preceding siblings ...)
  2005-05-10  5:04 ` [PATCH md 004 of 4] Make sure md/bitmap doesn't try to write a page with active writeback NeilBrown
@ 2005-05-10  5:04 ` NeilBrown
  3 siblings, 0 replies; 5+ messages in thread
From: NeilBrown @ 2005-05-10  5:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid


When a request crosses a boundary between devices, it needs to
be split.  But where we should calculate the amount of the request
before the boundary to find the split-point, we care currently calculating
the amount that is *after* the boundary !!!


Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>

### Diffstat output
 ./drivers/md/linear.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff ./drivers/md/linear.c~current~ ./drivers/md/linear.c
--- ./drivers/md/linear.c~current~	2005-05-10 14:25:28.000000000 +1000
+++ ./drivers/md/linear.c	2005-05-10 14:26:45.000000000 +1000
@@ -269,9 +269,8 @@ static int linear_make_request (request_
 		 * split it.
 		 */
 		struct bio_pair *bp;
-		bp = bio_split(bio, bio_split_pool, 
-			       (bio->bi_sector + (bio->bi_size >> 9) -
-				(tmp_dev->offset + tmp_dev->size))<<1);
+		bp = bio_split(bio, bio_split_pool,
+			       ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector);
 		if (linear_make_request(q, &bp->bio1))
 			generic_make_request(&bp->bio1);
 		if (linear_make_request(q, &bp->bio2))

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH md 003 of 4] Two small fixes for md verion-1 superblocks.
  2005-05-10  5:04 [PATCH md 000 of 4] Introduction NeilBrown
@ 2005-05-10  5:04 ` NeilBrown
  2005-05-10  5:04 ` [PATCH md 002 of 4] Set the unplug_fn and issue_flush_fn for md devices *after* committed to creation NeilBrown
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: NeilBrown @ 2005-05-10  5:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid


1/ Must typecast int to (sector_t) before inverting or we
 might not invert enough bits.

2/ When "bitmap_offset" was added to mdp_superblock_1, we didn't increase
   the count of words-used (96 to 100).

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>

### Diffstat output
 ./drivers/md/md.c           |    2 +-
 ./include/linux/raid/md_p.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff ./drivers/md/md.c~current~ ./drivers/md/md.c
--- ./drivers/md/md.c~current~	2005-05-10 14:32:54.000000000 +1000
+++ ./drivers/md/md.c	2005-05-10 14:33:18.000000000 +1000
@@ -847,7 +847,7 @@ static int super_1_load(mdk_rdev_t *rdev
 	case 0:
 		sb_offset = rdev->bdev->bd_inode->i_size >> 9;
 		sb_offset -= 8*2;
-		sb_offset &= ~(4*2-1);
+		sb_offset &= ~(sector_t)(4*2-1);
 		/* convert from sectors to K */
 		sb_offset /= 2;
 		break;

diff ./include/linux/raid/md_p.h~current~ ./include/linux/raid/md_p.h
--- ./include/linux/raid/md_p.h~current~	2005-05-10 14:32:49.000000000 +1000
+++ ./include/linux/raid/md_p.h	2005-05-10 14:33:33.000000000 +1000
@@ -202,7 +202,7 @@ struct mdp_superblock_1 {
 				 * NOTE: signed, so bitmap can be before superblock
 				 * only meaningful of feature_map[0] is set.
 				 */
-	__u8	pad1[128-96];	/* set to 0 when written */
+	__u8	pad1[128-100];	/* set to 0 when written */
 
 	/* constant this-device information - 64 bytes */
 	__u64	data_offset;	/* sector start of data, often 0 */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH md 004 of 4] Make sure md/bitmap doesn't try to write a page with active writeback
  2005-05-10  5:04 [PATCH md 000 of 4] Introduction NeilBrown
  2005-05-10  5:04 ` [PATCH md 003 of 4] Two small fixes for md verion-1 superblocks NeilBrown
  2005-05-10  5:04 ` [PATCH md 002 of 4] Set the unplug_fn and issue_flush_fn for md devices *after* committed to creation NeilBrown
@ 2005-05-10  5:04 ` NeilBrown
  2005-05-10  5:04 ` [PATCH md 001 of 4] Fix spliting of md/linear request that cross a device boundary NeilBrown
  3 siblings, 0 replies; 5+ messages in thread
From: NeilBrown @ 2005-05-10  5:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid


Due to the use of write-behind, it is possible for md to 
write a page to the bitmap file that is still completing writeback.
This is not allowed.

With this patch, we detect those cases and either force a sync write,
or back off and try later, as appropriate.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>

### Diffstat output
 ./drivers/md/bitmap.c |   68 +++++++++++++++++++++++++++-----------------------
 1 files changed, 38 insertions(+), 30 deletions(-)

diff ./drivers/md/bitmap.c~current~ ./drivers/md/bitmap.c
--- ./drivers/md/bitmap.c~current~	2005-05-10 14:44:11.000000000 +1000
+++ ./drivers/md/bitmap.c	2005-05-10 14:55:51.000000000 +1000
@@ -313,7 +313,16 @@ static int write_page(struct bitmap *bit
 	if (bitmap->file == NULL)
 		return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
 
-	lock_page(page);
+	if (wait)
+		lock_page(page);
+	else {
+		if (TestSetPageLocked(page))
+			return -EAGAIN; /* already locked */
+		if (PageWriteback(page)) {
+			unlock_page(page);
+			return -EAGAIN;
+		}
+	}
 
 	ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
 	if (!ret)
@@ -400,7 +409,7 @@ int bitmap_update_sb(struct bitmap *bitm
 	if (!bitmap->mddev->degraded)
 		sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
 	kunmap(bitmap->sb_page);
-	return write_page(bitmap, bitmap->sb_page, 0);
+	return write_page(bitmap, bitmap->sb_page, 1);
 }
 
 /* print out the bitmap file superblock */
@@ -762,6 +771,7 @@ int bitmap_unplug(struct bitmap *bitmap)
 	unsigned long i, attr, flags;
 	struct page *page;
 	int wait = 0;
+	int err;
 
 	if (!bitmap)
 		return 0;
@@ -782,9 +792,17 @@ int bitmap_unplug(struct bitmap *bitmap)
 			wait = 1;
 		spin_unlock_irqrestore(&bitmap->lock, flags);
 
-		if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE))
-			if (write_page(bitmap, page, 0))
+		if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) {
+			err = write_page(bitmap, page, 0);
+			if (err == -EAGAIN) {
+				if (attr & BITMAP_PAGE_DIRTY)
+					err = write_page(bitmap, page, 1);
+				else
+					err = 0;
+			}
+			if (err)
 				return 1;
+		}
 	}
 	if (wait) { /* if any writes were performed, we need to wait on them */
 		if (bitmap->file) {
@@ -1006,8 +1024,15 @@ int bitmap_daemon_work(struct bitmap *bi
 				}
 				spin_unlock_irqrestore(&bitmap->lock, flags);
 				if (attr & BITMAP_PAGE_NEEDWRITE) {
-					if (write_page(bitmap, page, 0))
+					switch (write_page(bitmap, page, 0)) {
+					case -EAGAIN:
+						set_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
+						break;
+					case 0:
+						break;
+					default:
 						bitmap_file_kick(bitmap);
+					}
 					page_cache_release(page);
 				}
 				continue;
@@ -1020,6 +1045,10 @@ int bitmap_daemon_work(struct bitmap *bi
 					clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
 					spin_unlock_irqrestore(&bitmap->lock, flags);
 					err = write_page(bitmap, lastpage, 0);
+					if (err == -EAGAIN) {
+						err = 0;
+						set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+					}
 				} else {
 					set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
 					spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1068,6 +1097,10 @@ int bitmap_daemon_work(struct bitmap *bi
 			clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
 			spin_unlock_irqrestore(&bitmap->lock, flags);
 			err = write_page(bitmap, lastpage, 0);
+			if (err == -EAGAIN) {
+				set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+				err = 0;
+			}
 		} else {
 			set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
 			spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1421,31 +1454,6 @@ static void bitmap_set_memory_bits(struc
 	}
 }
 
-/* dirty the entire bitmap */
-int bitmap_setallbits(struct bitmap *bitmap)
-{
-	unsigned long flags;
-	unsigned long j;
-
-	/* dirty the in-memory bitmap */
-	bitmap_set_memory_bits(bitmap, 0, bitmap->chunks << CHUNK_BLOCK_SHIFT(bitmap), 1);
-
-	/* dirty the bitmap file */
-	for (j = 0; j < bitmap->file_pages; j++) {
-		struct page *page = bitmap->filemap[j];
-
-		spin_lock_irqsave(&bitmap->lock, flags);
-		page_cache_get(page);
-		spin_unlock_irqrestore(&bitmap->lock, flags);
-		memset(kmap(page), 0xff, PAGE_SIZE);
-		kunmap(page);
-		if (write_page(bitmap, page, 0))
-			return 1;
-	}
-
-	return 0;
-}
-
 /*
  * free memory that was allocated
  */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH md 002 of 4] Set the unplug_fn and issue_flush_fn for md devices *after* committed to creation.
  2005-05-10  5:04 [PATCH md 000 of 4] Introduction NeilBrown
  2005-05-10  5:04 ` [PATCH md 003 of 4] Two small fixes for md verion-1 superblocks NeilBrown
@ 2005-05-10  5:04 ` NeilBrown
  2005-05-10  5:04 ` [PATCH md 004 of 4] Make sure md/bitmap doesn't try to write a page with active writeback NeilBrown
  2005-05-10  5:04 ` [PATCH md 001 of 4] Fix spliting of md/linear request that cross a device boundary NeilBrown
  3 siblings, 0 replies; 5+ messages in thread
From: NeilBrown @ 2005-05-10  5:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-raid


We we set the too early, they may still be in place and possibly get called
even though the array didn't get set up properly.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>

### Diffstat output
 ./drivers/md/multipath.c |    8 ++++----
 ./drivers/md/raid1.c     |    7 +++----
 ./drivers/md/raid10.c    |    6 +++---
 ./drivers/md/raid5.c     |    7 ++++---
 ./drivers/md/raid6main.c |    6 +++---
 5 files changed, 17 insertions(+), 17 deletions(-)

diff ./drivers/md/multipath.c~current~ ./drivers/md/multipath.c
--- ./drivers/md/multipath.c~current~	2005-05-10 14:30:02.000000000 +1000
+++ ./drivers/md/multipath.c	2005-05-10 14:29:15.000000000 +1000
@@ -462,10 +462,6 @@ static int multipath_run (mddev_t *mddev
 	}
 	memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks);
 
-	mddev->queue->unplug_fn = multipath_unplug;
-
-	mddev->queue->issue_flush_fn = multipath_issue_flush;
-
 	conf->working_disks = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		disk_idx = rdev->raid_disk;
@@ -528,6 +524,10 @@ static int multipath_run (mddev_t *mddev
 	 * Ok, everything is just fine now
 	 */
 	mddev->array_size = mddev->size;
+
+	mddev->queue->unplug_fn = multipath_unplug;
+	mddev->queue->issue_flush_fn = multipath_issue_flush;
+
 	return 0;
 
 out_free_conf:

diff ./drivers/md/raid1.c~current~ ./drivers/md/raid1.c
--- ./drivers/md/raid1.c~current~	2005-05-10 14:30:02.000000000 +1000
+++ ./drivers/md/raid1.c	2005-05-10 14:29:15.000000000 +1000
@@ -1331,10 +1331,6 @@ static int run(mddev_t *mddev)
 	if (!conf->r1bio_pool)
 		goto out_no_mem;
 
-	mddev->queue->unplug_fn = raid1_unplug;
-
-	mddev->queue->issue_flush_fn = raid1_issue_flush;
-
 	ITERATE_RDEV(mddev, rdev, tmp) {
 		disk_idx = rdev->raid_disk;
 		if (disk_idx >= mddev->raid_disks
@@ -1418,6 +1414,9 @@ static int run(mddev_t *mddev)
 	 */
 	mddev->array_size = mddev->size;
 
+	mddev->queue->unplug_fn = raid1_unplug;
+	mddev->queue->issue_flush_fn = raid1_issue_flush;
+
 	return 0;
 
 out_no_mem:

diff ./drivers/md/raid10.c~current~ ./drivers/md/raid10.c
--- ./drivers/md/raid10.c~current~	2005-05-10 14:30:02.000000000 +1000
+++ ./drivers/md/raid10.c	2005-05-10 14:29:15.000000000 +1000
@@ -1645,9 +1645,6 @@ static int run(mddev_t *mddev)
 			mdname(mddev));
 		goto out_free_conf;
 	}
-	mddev->queue->unplug_fn = raid10_unplug;
-
-	mddev->queue->issue_flush_fn = raid10_issue_flush;
 
 	ITERATE_RDEV(mddev, rdev, tmp) {
 		disk_idx = rdev->raid_disk;
@@ -1719,6 +1716,9 @@ static int run(mddev_t *mddev)
 	mddev->array_size = size/2;
 	mddev->resync_max_sectors = size;
 
+	mddev->queue->unplug_fn = raid10_unplug;
+	mddev->queue->issue_flush_fn = raid10_issue_flush;
+
 	/* Calculate max read-ahead size.
 	 * We need to readahead at least twice a whole stripe....
 	 * maybe...

diff ./drivers/md/raid5.c~current~ ./drivers/md/raid5.c
--- ./drivers/md/raid5.c~current~	2005-05-10 14:30:02.000000000 +1000
+++ ./drivers/md/raid5.c	2005-05-10 14:29:15.000000000 +1000
@@ -1620,9 +1620,6 @@ static int run (mddev_t *mddev)
 	atomic_set(&conf->active_stripes, 0);
 	atomic_set(&conf->preread_active_stripes, 0);
 
-	mddev->queue->unplug_fn = raid5_unplug_device;
-	mddev->queue->issue_flush_fn = raid5_issue_flush;
-
 	PRINTK("raid5: run(%s) called.\n", mdname(mddev));
 
 	ITERATE_RDEV(mddev,rdev,tmp) {
@@ -1728,6 +1725,10 @@ memory = conf->max_nr_stripes * (sizeof(
 	}
 
 	/* Ok, everything is just fine now */
+
+	mddev->queue->unplug_fn = raid5_unplug_device;
+	mddev->queue->issue_flush_fn = raid5_issue_flush;
+
 	mddev->array_size =  mddev->size * (mddev->raid_disks - 1);
 	return 0;
 abort:

diff ./drivers/md/raid6main.c~current~ ./drivers/md/raid6main.c
--- ./drivers/md/raid6main.c~current~	2005-05-10 14:30:02.000000000 +1000
+++ ./drivers/md/raid6main.c	2005-05-10 14:29:15.000000000 +1000
@@ -1779,9 +1779,6 @@ static int run (mddev_t *mddev)
 	atomic_set(&conf->active_stripes, 0);
 	atomic_set(&conf->preread_active_stripes, 0);
 
-	mddev->queue->unplug_fn = raid6_unplug_device;
-	mddev->queue->issue_flush_fn = raid6_issue_flush;
-
 	PRINTK("raid6: run(%s) called.\n", mdname(mddev));
 
 	ITERATE_RDEV(mddev,rdev,tmp) {
@@ -1895,6 +1892,9 @@ static int run (mddev_t *mddev)
 
 	/* Ok, everything is just fine now */
 	mddev->array_size =  mddev->size * (mddev->raid_disks - 2);
+
+	mddev->queue->unplug_fn = raid6_unplug_device;
+	mddev->queue->issue_flush_fn = raid6_issue_flush;
 	return 0;
 abort:
 	if (conf) {

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-05-10  5:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-10  5:04 [PATCH md 000 of 4] Introduction NeilBrown
2005-05-10  5:04 ` [PATCH md 003 of 4] Two small fixes for md verion-1 superblocks NeilBrown
2005-05-10  5:04 ` [PATCH md 002 of 4] Set the unplug_fn and issue_flush_fn for md devices *after* committed to creation NeilBrown
2005-05-10  5:04 ` [PATCH md 004 of 4] Make sure md/bitmap doesn't try to write a page with active writeback NeilBrown
2005-05-10  5:04 ` [PATCH md 001 of 4] Fix spliting of md/linear request that cross a device boundary NeilBrown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox