[patch 0/7] Add TRIM support for raid linear/0/1/10

STALE5248d

16 messages, 7 authors, 2012-03-18 · open the first message on its own page

[patch 0/7] Add TRIM support for raid linear/0/1/10

From: Shaohua Li <hidden>
Date: 2012-03-12 03:13:18

The patches add TRIM support for raid linear/0/1/10. I'll add TRIM support for
raid 4/5/6 later. The implementation is pretty straightforward and
self-explained.

Thanks,
Shaohua

[patch 1/7] block: makes bio_split support bio without data

From: Shaohua Li <hidden>
Date: 2012-03-12 03:13:43

discard bio hasn't data attached. We hit a BUG_ON with such bio. This makes
bio_split works for such bio.

Signed-off-by: Shaohua Li <redacted>
---
 fs/bio.c |   22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

Index: linux/fs/bio.c
===================================================================
--- linux.orig/fs/bio.c	2012-03-09 16:56:41.203790008 +0800
+++ linux/fs/bio.c	2012-03-12 10:10:40.696612399 +0800
@@ -1492,7 +1492,7 @@ struct bio_pair *bio_split(struct bio *b
 	trace_block_split(bdev_get_queue(bi->bi_bdev), bi,
 				bi->bi_sector + first_sectors);
 
-	BUG_ON(bi->bi_vcnt != 1);
+	BUG_ON(bi->bi_vcnt != 1 && bi->bi_vcnt != 0);
 	BUG_ON(bi->bi_idx != 0);
 	atomic_set(&bp->cnt, 3);
 	bp->error = 0;
@@ -1502,17 +1502,19 @@ struct bio_pair *bio_split(struct bio *b
 	bp->bio2.bi_size -= first_sectors << 9;
 	bp->bio1.bi_size = first_sectors << 9;
 
-	bp->bv1 = bi->bi_io_vec[0];
-	bp->bv2 = bi->bi_io_vec[0];
-	bp->bv2.bv_offset += first_sectors << 9;
-	bp->bv2.bv_len -= first_sectors << 9;
-	bp->bv1.bv_len = first_sectors << 9;
+	if (bi->bi_vcnt != 0) {
+		bp->bv1 = bi->bi_io_vec[0];
+		bp->bv2 = bi->bi_io_vec[0];
+		bp->bv2.bv_offset += first_sectors << 9;
+		bp->bv2.bv_len -= first_sectors << 9;
+		bp->bv1.bv_len = first_sectors << 9;
 
-	bp->bio1.bi_io_vec = &bp->bv1;
-	bp->bio2.bi_io_vec = &bp->bv2;
+		bp->bio1.bi_io_vec = &bp->bv1;
+		bp->bio2.bi_io_vec = &bp->bv2;
 
-	bp->bio1.bi_max_vecs = 1;
-	bp->bio2.bi_max_vecs = 1;
+		bp->bio1.bi_max_vecs = 1;
+		bp->bio2.bi_max_vecs = 1;
+	}
 
 	bp->bio1.bi_end_io = bio_pair_end_1;
 	bp->bio2.bi_end_io = bio_pair_end_2;

[patch 2/7] md: linear supports TRIM

From: Shaohua Li <hidden>
Date: 2012-03-12 03:13:53

This makes md linear support TRIM.

Signed-off-by: Shaohua Li <redacted>
---
 drivers/md/linear.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Index: linux/drivers/md/linear.c
===================================================================
--- linux.orig/drivers/md/linear.c	2012-03-09 16:56:41.173790011 +0800
+++ linux/drivers/md/linear.c	2012-03-12 10:15:44.916611071 +0800
@@ -129,6 +129,7 @@ static struct linear_conf *linear_conf(s
 	struct linear_conf *conf;
 	struct md_rdev *rdev;
 	int i, cnt;
+	bool discard_supported = false;
 
 	conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(struct dev_info),
 			GFP_KERNEL);
@@ -171,6 +172,8 @@ static struct linear_conf *linear_conf(s
 		conf->array_sectors += rdev->sectors;
 		cnt++;
 
+		if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+			discard_supported = true;
 	}
 	if (cnt != raid_disks) {
 		printk(KERN_ERR "md/linear:%s: not enough drives present. Aborting!\n",
@@ -178,6 +181,11 @@ static struct linear_conf *linear_conf(s
 		goto out;
 	}
 
+	if (!discard_supported)
+		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+	else
+		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
 	/*
 	 * Here we calculate the device offsets.
 	 */
@@ -319,6 +327,14 @@ static void linear_make_request(struct m
 	bio->bi_sector = bio->bi_sector - start_sector
 		+ tmp_dev->rdev->data_offset;
 	rcu_read_unlock();
+
+	if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+		!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
+		/* Just ignore it */
+		bio_endio(bio, 0);
+		return;
+	}
+
 	generic_make_request(bio);
 }
 

[patch 3/7] md: raid 0 supports TRIM

From: Shaohua Li <hidden>
Date: 2012-03-12 03:14:03

This makes md raid 0 support TRIM.

Signed-off-by: Shaohua Li <redacted>
---
 drivers/md/raid0.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Index: linux/drivers/md/raid0.c
===================================================================
--- linux.orig/drivers/md/raid0.c	2012-03-09 16:56:41.133790013 +0800
+++ linux/drivers/md/raid0.c	2012-03-12 10:16:18.526610922 +0800
@@ -88,6 +88,7 @@ static int create_strip_zones(struct mdd
 	char b[BDEVNAME_SIZE];
 	char b2[BDEVNAME_SIZE];
 	struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
+	bool discard_supported = false;
 
 	if (!conf)
 		return -ENOMEM;
@@ -201,6 +202,9 @@ static int create_strip_zones(struct mdd
 		if (!smallest || (rdev1->sectors < smallest->sectors))
 			smallest = rdev1;
 		cnt++;
+
+		if (blk_queue_discard(bdev_get_queue(rdev1->bdev)))
+			discard_supported = true;
 	}
 	if (cnt != mddev->raid_disks) {
 		printk(KERN_ERR "md/raid0:%s: too few disks (%d of %d) - "
@@ -278,6 +282,11 @@ static int create_strip_zones(struct mdd
 	blk_queue_io_opt(mddev->queue,
 			 (mddev->chunk_sectors << 9) * mddev->raid_disks);
 
+	if (!discard_supported)
+		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+	else
+		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
 	pr_debug("md/raid0:%s: done.\n", mdname(mddev));
 	*private_conf = conf;
 
@@ -348,6 +357,7 @@ static int raid0_run(struct mddev *mddev
 	if (md_check_no_bitmap(mddev))
 		return -EINVAL;
 	blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
+	blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors);
 
 	/* if private is not null, we are here after takeover */
 	if (mddev->private == NULL) {
@@ -512,6 +522,13 @@ static void raid0_make_request(struct md
 	bio->bi_sector = sector_offset + zone->dev_start +
 		tmp_dev->data_offset;
 
+	if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+		!blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
+		/* Just ignore it */
+		bio_endio(bio, 0);
+		return;
+	}
+
 	generic_make_request(bio);
 	return;
 

[patch 4/7] md: raid 1 supports TRIM

From: Shaohua Li <hidden>
Date: 2012-03-12 03:14:07

This makes md raid 1 support TRIM.
If one disk supports discard and another not, or one has discard_zero_data and
another not, there could be inconsistent between data from such disks. But this
should not matter, discarded data is useless. This will add extra copy in rebuild
though.

Signed-off-by: Shaohua Li <redacted>
---
 drivers/md/raid1.c |   21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

Index: linux/drivers/md/raid1.c
===================================================================
--- linux.orig/drivers/md/raid1.c	2012-03-12 10:09:42.426612652 +0800
+++ linux/drivers/md/raid1.c	2012-03-12 10:16:50.276610783 +0800
@@ -673,7 +673,12 @@ static void flush_pending_writes(struct
 		while (bio) { /* submit pending writes */
 			struct bio *next = bio->bi_next;
 			bio->bi_next = NULL;
-			generic_make_request(bio);
+			if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+			    !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
+				/* Just ignore it */
+				bio_endio(bio, 0);
+			else
+				generic_make_request(bio);
 			bio = next;
 		}
 	} else
@@ -835,6 +840,7 @@ static void make_request(struct mddev *m
 	const int rw = bio_data_dir(bio);
 	const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
 	const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
+	const unsigned long do_discard = (bio->bi_rw & (REQ_DISCARD | REQ_SECURE));
 	struct md_rdev *blocked_rdev;
 	int plugged;
 	int first_clone;
@@ -1135,7 +1141,7 @@ read_again:
 				   conf->mirrors[i].rdev->data_offset);
 		mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
 		mbio->bi_end_io	= raid1_end_write_request;
-		mbio->bi_rw = WRITE | do_flush_fua | do_sync;
+		mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard;
 		mbio->bi_private = r1_bio;
 
 		atomic_inc(&r1_bio->remaining);
@@ -1371,6 +1377,8 @@ static int raid1_add_disk(struct mddev *
 		}
 	}
 	md_integrity_add_rdev(rdev, mddev);
+	if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
 	print_conf(conf);
 	return err;
 }
@@ -2585,6 +2593,7 @@ static int run(struct mddev *mddev)
 	struct r1conf *conf;
 	int i;
 	struct md_rdev *rdev;
+	bool discard_supported = false;
 
 	if (mddev->level != 1) {
 		printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n",
@@ -2623,8 +2632,16 @@ static int run(struct mddev *mddev)
 			blk_queue_segment_boundary(mddev->queue,
 						   PAGE_CACHE_SIZE - 1);
 		}
+
+		if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+			discard_supported = true;
 	}
 
+	if (discard_supported)
+		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+	else
+		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
 	mddev->degraded = 0;
 	for (i=0; i < conf->raid_disks; i++)
 		if (conf->mirrors[i].rdev == NULL ||

[patch 5/7] md: raid 10 supports TRIM

From: Shaohua Li <hidden>
Date: 2012-03-12 03:14:14

This makes md raid 10 support TRIM.
If one disk supports discard and another not, or one has discard_zero_data and
another not, there could be inconsistent between data from such disks. But this
should not matter, discarded data is useless. This will add extra copy in rebuild
though.

Signed-off-by: Shaohua Li <redacted>
---
 drivers/md/raid10.c |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

Index: linux/drivers/md/raid10.c
===================================================================
--- linux.orig/drivers/md/raid10.c	2012-03-12 10:09:42.426612652 +0800
+++ linux/drivers/md/raid10.c	2012-03-12 10:19:05.046610195 +0800
@@ -800,7 +800,12 @@ static void flush_pending_writes(struct
 		while (bio) { /* submit pending writes */
 			struct bio *next = bio->bi_next;
 			bio->bi_next = NULL;
-			generic_make_request(bio);
+			if (unlikely((bio->bi_rw & REQ_DISCARD) &&
+			    !blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
+				/* Just ignore it */
+				bio_endio(bio, 0);
+			else
+				generic_make_request(bio);
 			bio = next;
 		}
 	} else
@@ -926,6 +931,7 @@ static void make_request(struct mddev *m
 	const int rw = bio_data_dir(bio);
 	const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
 	const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
+	const unsigned long do_discard = (bio->bi_rw & (REQ_DISCARD | REQ_SECURE));
 	unsigned long flags;
 	struct md_rdev *blocked_rdev;
 	int plugged;
@@ -1241,7 +1247,7 @@ retry_write:
 				   conf->mirrors[d].rdev->data_offset);
 		mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
 		mbio->bi_end_io	= raid10_end_write_request;
-		mbio->bi_rw = WRITE | do_sync | do_fua;
+		mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
 		mbio->bi_private = r10_bio;
 
 		atomic_inc(&r10_bio->remaining);
@@ -1266,7 +1272,7 @@ retry_write:
 				   conf->mirrors[d].replacement->data_offset);
 		mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
 		mbio->bi_end_io	= raid10_end_write_request;
-		mbio->bi_rw = WRITE | do_sync | do_fua;
+		mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
 		mbio->bi_private = r10_bio;
 
 		atomic_inc(&r10_bio->remaining);
@@ -1543,6 +1549,9 @@ static int raid10_add_disk(struct mddev
 	}
 
 	md_integrity_add_rdev(rdev, mddev);
+	if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
 	print_conf(conf);
 	return err;
 }
@@ -3214,6 +3223,7 @@ static int run(struct mddev *mddev)
 	struct mirror_info *disk;
 	struct md_rdev *rdev;
 	sector_t size;
+	bool discard_supported = false;
 
 	/*
 	 * copy the already verified devices into our private RAID10
@@ -3234,6 +3244,7 @@ static int run(struct mddev *mddev)
 	mddev->thread = conf->thread;
 	conf->thread = NULL;
 
+	blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors);
 	chunk_size = mddev->chunk_sectors << 9;
 	blk_queue_io_min(mddev->queue, chunk_size);
 	if (conf->raid_disks % conf->near_copies)
@@ -3273,7 +3284,16 @@ static int run(struct mddev *mddev)
 		}
 
 		disk->head_position = 0;
+
+		if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+			discard_supported = true;
 	}
+
+	if (discard_supported)
+		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+	else
+		queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
+
 	/* need to check that every block has at least one working mirror */
 	if (!enough(conf, -1)) {
 		printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n",

[patch 7/7] blk: use correct sectors limitation for discard request

From: Shaohua Li <hidden>
Date: 2012-03-12 03:14:17

max_discard_sectors doesn't equal to max_sectors/max_hw_sectors. Without this,
discard request merge might be ignored.

Signed-off-by: Shaohua Li <redacted>
---
 block/blk-merge.c      |    9 +++++++--
 include/linux/blkdev.h |    5 +++++
 2 files changed, 12 insertions(+), 2 deletions(-)

Index: linux/block/blk-merge.c
===================================================================
--- linux.orig/block/blk-merge.c	2012-03-09 14:05:35.562062857 +0800
+++ linux/block/blk-merge.c	2012-03-09 14:07:55.432062246 +0800
@@ -228,13 +228,16 @@ no_merge:
 int ll_back_merge_fn(struct request_queue *q, struct request *req,
 		     struct bio *bio)
 {
-	unsigned short max_sectors;
+	unsigned int max_sectors;
 
 	if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
 		max_sectors = queue_max_hw_sectors(q);
 	else
 		max_sectors = queue_max_sectors(q);
 
+	if (unlikely(req->cmd_flags & REQ_DISCARD))
+		max_sectors = queue_max_discard_sectors(q);
+
 	if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
 		req->cmd_flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
@@ -252,13 +255,15 @@ int ll_back_merge_fn(struct request_queu
 int ll_front_merge_fn(struct request_queue *q, struct request *req,
 		      struct bio *bio)
 {
-	unsigned short max_sectors;
+	unsigned int max_sectors;
 
 	if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
 		max_sectors = queue_max_hw_sectors(q);
 	else
 		max_sectors = queue_max_sectors(q);
 
+	if (unlikely(req->cmd_flags & REQ_DISCARD))
+		max_sectors = queue_max_discard_sectors(q);
 
 	if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
 		req->cmd_flags |= REQ_NOMERGE;
Index: linux/include/linux/blkdev.h
===================================================================
--- linux.orig/include/linux/blkdev.h	2012-03-09 14:05:35.562062857 +0800
+++ linux/include/linux/blkdev.h	2012-03-09 14:07:55.432062246 +0800
@@ -1006,6 +1006,11 @@ static inline unsigned int queue_max_hw_
 	return q->limits.max_hw_sectors;
 }
 
+static inline unsigned int queue_max_discard_sectors(struct request_queue *q)
+{
+	return q->limits.max_discard_sectors;
+}
+
 static inline unsigned short queue_max_segments(struct request_queue *q)
 {
 	return q->limits.max_segments;

Re: [patch 7/7] blk: use correct sectors limitation for discard request

From: Vivek Goyal <vgoyal@redhat.com>
Date: 2012-03-13 16:00:30

On Mon, Mar 12, 2012 at 11:04:19AM +0800, Shaohua Li wrote:
quoted hunk
max_discard_sectors doesn't equal to max_sectors/max_hw_sectors. Without this,
discard request merge might be ignored.

Signed-off-by: Shaohua Li <redacted>
---
 block/blk-merge.c      |    9 +++++++--
 include/linux/blkdev.h |    5 +++++
 2 files changed, 12 insertions(+), 2 deletions(-)

Index: linux/block/blk-merge.c
===================================================================
--- linux.orig/block/blk-merge.c	2012-03-09 14:05:35.562062857 +0800
+++ linux/block/blk-merge.c	2012-03-09 14:07:55.432062246 +0800
@@ -228,13 +228,16 @@ no_merge:
 int ll_back_merge_fn(struct request_queue *q, struct request *req,
 		     struct bio *bio)
 {
-	unsigned short max_sectors;
+	unsigned int max_sectors;
 
 	if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
 		max_sectors = queue_max_hw_sectors(q);
 	else
 		max_sectors = queue_max_sectors(q);
 
+	if (unlikely(req->cmd_flags & REQ_DISCARD))
+		max_sectors = queue_max_discard_sectors(q);
+
May be make above check an "else if" condition above instead of starting
another "if" block.

Thanks
Vivek

[patch 6/7] blk: add plug for blkdev_issue_discard

From: Shaohua Li <hidden>
Date: 2012-03-12 03:14:26

In raid 0 case, a big discard request is divided into several small requests
in chunk_size unit. Such requests can be merged in low layer if we have
correct plug added. This should improve the performance a little bit.

raid 10 case doesn't matter, as we dispatch request in a separate thread
and there is plug there.

Signed-off-by: Shaohua Li <redacted>
---
 block/blk-lib.c |    3 +++
 1 file changed, 3 insertions(+)

Index: linux/block/blk-lib.c
===================================================================
--- linux.orig/block/blk-lib.c	2012-03-09 16:56:41.043790011 +0800
+++ linux/block/blk-lib.c	2012-03-12 10:21:38.716609525 +0800
@@ -47,6 +47,7 @@ int blkdev_issue_discard(struct block_de
 	struct bio_batch bb;
 	struct bio *bio;
 	int ret = 0;
+	struct blk_plug plug;
 
 	if (!q)
 		return -ENXIO;
@@ -78,6 +79,7 @@ int blkdev_issue_discard(struct block_de
 	bb.flags = 1 << BIO_UPTODATE;
 	bb.wait = &wait;
 
+	blk_start_plug(&plug);
 	while (nr_sects) {
 		bio = bio_alloc(gfp_mask, 1);
 		if (!bio) {
@@ -102,6 +104,7 @@ int blkdev_issue_discard(struct block_de
 		atomic_inc(&bb.done);
 		submit_bio(type, bio);
 	}
+	blk_finish_plug(&plug);
 
 	/* Wait for bios in-flight */
 	if (!atomic_dec_and_test(&bb.done))

Re: [patch 6/7] blk: add plug for blkdev_issue_discard

From: Vivek Goyal <vgoyal@redhat.com>
Date: 2012-03-13 15:51:34

On Mon, Mar 12, 2012 at 11:04:18AM +0800, Shaohua Li wrote:
In raid 0 case, a big discard request is divided into several small requests
in chunk_size unit. Such requests can be merged in low layer if we have
correct plug added. This should improve the performance a little bit.
Martin posted a patch to remove the support for allowing merging of discard
requests. But this seems to be a reasonable use case for allowing mering
discard requests. CCing Martin.

Thanks
Vivek

Re: [patch 0/7] Add TRIM support for raid linear/0/1/10

From: Roberto Spadim <hidden>
Date: 2012-03-12 03:18:42

nice!

Em 12 de março de 2012 00:04, Shaohua Li [off-list ref] escreveu:
The patches add TRIM support for raid linear/0/1/10. I'll add TRIM support for
raid 4/5/6 later. The implementation is pretty straightforward and
self-explained.

Thanks,
Shaohua
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Roberto Spadim
Spadim Technology / SPAEmpresarial
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [patch 0/7] Add TRIM support for raid linear/0/1/10

From: Holger Kiehl <hidden>
Date: 2012-03-12 18:34:10

Hello,

On Mon, 12 Mar 2012, Shaohua Li wrote:
The patches add TRIM support for raid linear/0/1/10. I'll add TRIM support for
raid 4/5/6 later. The implementation is pretty straightforward and
self-explained.
First, thanks for this patch!

I have applied those patches against 3.3.0-rc7 and during boot the kernel
reports a lot of the following:

    Mar 12 18:56:00 c3po kernel: [    7.611045] md/raid0:md3: make_request bug: can't convert block across chunks or bigger than 512k 18861064 512
    Mar 12 18:56:00 c3po kernel: [    7.611047] md/raid0:md3: make_request bug: can't convert block across chunks or bigger than 512k 18862088 512
    Mar 12 18:56:00 c3po kernel: [    7.611049] md/raid0:md3: make_request bug: can't convert block across chunks or bigger than 512k 18863112 512
    Mar 12 18:56:00 c3po kernel: [    7.611052] md/raid0:md3: make_request bug: can't convert block across chunks or bigger than 512k 18864136 512
    Mar 12 18:56:00 c3po kernel: [    7.611054] md/raid0:md3: make_request bug: can't convert block across chunks or bigger than 512k 18865160 512
    Mar 12 18:56:00 c3po kernel: [    7.611056] md/raid0:md3: make_request bug: can't convert block across chunks or bigger than 512k 18866184 512

The raid looks as follows:

   cat /proc/mdstat
   Personalities : [raid0] [raid1]
   md2 : active raid0 sdc3[2] sdb3[1] sda3[0]
         50328576 blocks super 1.1 512k chunks

   md0 : active raid1 sdc1[1] sdb1[2]
         245748 blocks super 1.0 [2/2] [UU]

   md3 : active raid0 sdc5[2] sda5[0] sdb5[1]
         9434112 blocks super 1.1 512k chunks

   md1 : active raid0 sdc2[2] sda2[0] sdb2[1]
         22017024 blocks super 1.1 512k chunks

   unused devices: <none>

/dev/md3 is the swap partition.

I also get these reports from /dev/md2 which is my /home partition:

    Mar 12 19:06:42 c3po kernel: [  658.419035] md/raid0:md2: make_request bug: can't convert block across chunks or bigger than 512k 152088 512
    Mar 12 19:06:42 c3po kernel: [  658.419042] md/raid0:md2: make_request bug: can't convert block across chunks or bigger than 512k 153112 512
    Mar 12 19:06:42 c3po kernel: [  658.451489] md/raid0:md2: make_request bug: can't convert block across chunks or bigger than 512k 3206944 512
    Mar 12 19:06:42 c3po kernel: [  658.451494] md/raid0:md2: make_request bug: can't convert block across chunks or bigger than 512k 3207968 512
    Mar 12 19:06:42 c3po kernel: [  658.451499] md/raid0:md2: make_request bug: can't convert block across chunks or bigger than 512k 3208992 164

I then did a 'make clean' in my kernel tree which is on /dev/md1. After a
sync, which took very long the following errors appear:

    Mar 12 19:12:34 c3po kernel: [ 1010.609388] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9986936 512
    Mar 12 19:12:34 c3po kernel: [ 1010.609393] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9987960 512
    Mar 12 19:12:34 c3po kernel: [ 1010.609396] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9988984 512
    Mar 12 19:12:34 c3po kernel: [ 1010.670542] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 11535480 512
    Mar 12 19:12:34 c3po kernel: [ 1010.787087] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 8998632 160
    Mar 12 19:12:34 c3po kernel: [ 1010.799357] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9037136 476
    Mar 12 19:12:34 c3po kernel: [ 1010.807195] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 8999792 512
    Mar 12 19:12:34 c3po kernel: [ 1010.807201] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9000816 108
    Mar 12 19:12:34 c3po kernel: [ 1010.899348] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 8996824 28
    Mar 12 19:12:34 c3po kernel: [ 1010.905625] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9977808 512
    Mar 12 19:12:34 c3po kernel: [ 1010.905631] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9978832 512
    Mar 12 19:12:34 c3po kernel: [ 1010.905636] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9979856 512
    Mar 12 19:12:34 c3po kernel: [ 1010.905641] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9980880 44
    Mar 12 19:12:34 c3po kernel: [ 1011.145590] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 8940504 72
       .
       .
       .
    Mar 12 19:12:37 c3po kernel: [ 1013.781899] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9036704 208
    Mar 12 19:12:37 c3po kernel: [ 1013.781910] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 9040824 76
    Mar 12 19:12:37 c3po kernel: [ 1013.901750] md/raid0:md1: make_request bug: can't convert block across chunks or bigger than 512k 8841152 64
    Mar 12 19:12:37 c3po kernel: [ 1014.015810] request botched: dev sda: type=1, flags=9164081
    Mar 12 19:12:37 c3po kernel: [ 1014.015814]   sector 2615297, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.015818]   bio ffff880193fd4140, biotail ffff880193fd45c0, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.017423] request botched: dev sdc: type=1, flags=9164081
    Mar 12 19:12:37 c3po kernel: [ 1014.017426]   sector 2614273, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.017430]   bio ffff880193fd4080, biotail ffff880193fd4500, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.019569] request botched: dev sdb: type=1, flags=9164081
    Mar 12 19:12:37 c3po kernel: [ 1014.019572]   sector 2614273, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.019576]   bio ffff88016e1fb2c0, biotail ffff880193fd4680, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.025916] request botched: dev sda: type=1, flags=916c081
    Mar 12 19:12:37 c3po kernel: [ 1014.025920]   sector 2615298, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.025923]   bio ffff880193fd4380, biotail ffff880193fd45c0, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.027496] request botched: dev sdc: type=1, flags=916c081
    Mar 12 19:12:37 c3po kernel: [ 1014.027499]   sector 2614274, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.027503]   bio ffff880193fd42c0, biotail ffff880193fd4500, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.034183] request botched: dev sdb: type=1, flags=916c081
    Mar 12 19:12:37 c3po kernel: [ 1014.034187]   sector 2614274, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.034190]   bio ffff880193fd4200, biotail ffff880193fd4680, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.037478] request botched: dev sdc: type=1, flags=916c081
    Mar 12 19:12:37 c3po kernel: [ 1014.037482]   sector 2614275, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.037485]   bio ffff880193fd4500, biotail ffff880193fd4500, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.039616] request botched: dev sdb: type=1, flags=916c081
    Mar 12 19:12:37 c3po kernel: [ 1014.039620]   sector 2614275, nr/cnr 0/1024
    Mar 12 19:12:37 c3po kernel: [ 1014.039623]   bio ffff880193fd4440, biotail ffff880193fd4680, buffer           (null), len 0
    Mar 12 19:12:37 c3po kernel: [ 1014.040477] request botched: dev sda: type=1, flags=916c081
    Mar 12 19:12:37 c3po kernel: [ 1014.040481]   sector 2615299, nr/cnr 0/1024
       .
       .
       .

The list goes on for very long. Here the mount options:

    /dev/md1 / ext4 rw,noatime,user_xattr,commit=600,barrier=1,journal_async_commit,stripe=384,data=ordered,discard 0 0
    /dev/md0 /boot ext4 rw,noatime,user_xattr,commit=2400,barrier=1,journal_async_commit,data=ordered,discard 0 0
    /dev/md2 /home ext4 rw,noatime,user_xattr,acl,commit=600,barrier=1,journal_async_commit,stripe=384,data=ordered,discard 0 0

The disk in use are the following:

    Mar 12 09:03:57 c3po kernel: [    1.206716] ata2.00: ATA-8: OCZ-VERTEX2, 1.35, max UDMA/133
    Mar 12 09:03:57 c3po kernel: [    1.208374] ata2.00: 234441648 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
    Mar 12 09:03:57 c3po kernel: [    1.209939] ata1.00: ATA-8: OCZ-VERTEX2, 1.35, max UDMA/133
    Mar 12 09:03:57 c3po kernel: [    1.211507] ata1.00: 234441648 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
    Mar 12 09:03:57 c3po kernel: [    1.216427] ata3.00: ATA-8: OCZ-VERTEX2, 1.35, max UDMA/133
    Mar 12 09:03:57 c3po kernel: [    1.218064] ata3.00: 234441648 sectors, multi 16: LBA48 NCQ (depth 31/32), AA


Any idea what is wrong? Please let me know if I can do any further tests
or supply more information.

Regards,
Holger

Re: [patch 0/7] Add TRIM support for raid linear/0/1/10

From: NeilBrown <hidden>
Date: 2012-03-14 02:24:32

On Mon, 12 Mar 2012 11:04:12 +0800 Shaohua Li [off-list ref] wrote:
The patches add TRIM support for raid linear/0/1/10. I'll add TRIM support for
raid 4/5/6 later. The implementation is pretty straightforward and
self-explained.

Thanks,
Shaohua
Thanks.
They look mostly OK.

In raid0.c, I think you'll need to change

		/* Sanity check -- queue functions should prevent this happening */
		if (bio->bi_vcnt != 1 ||
		    bio->bi_idx != 0)
			goto bad_map;

to also allow for 'bi_vcnt == 0' like you did in bio_split.

Also I wonder about handling failure in RAID1.
I think the code will currently treat it like a write error, and
maybe record a bad block (then fail the device is writing the badblock
record fails). Is that what were want?

And of course resync/recovery will mess up the discarded sector information,
so this isn't a complete solution for RAID1.  But  it is a reasonable start.

Thanks,
NeilBrown

Re: [patch 0/7] Add TRIM support for raid linear/0/1/10

From: Shaohua Li <shli@kernel.org>
Date: 2012-03-14 02:47:42

On 3/14/12 10:24 AM, NeilBrown wrote:
 On Mon, 12 Mar 2012 11:04:12 +0800 Shaohua Li [off-list ref] wrote:
quoted
The patches add TRIM support for raid linear/0/1/10. I'll add TRIM 
support for
quoted
raid 4/5/6 later. The implementation is pretty straightforward and
self-explained.

Thanks,
Shaohua
 Thanks.
 They look mostly OK.

 In raid0.c, I think you'll need to change

 /* Sanity check -- queue functions should prevent this happening */
 if (bio->bi_vcnt != 1 ||
 bio->bi_idx != 0)
 goto bad_map;

 to also allow for 'bi_vcnt == 0' like you did in bio_split.

 Also I wonder about handling failure in RAID1.
 I think the code will currently treat it like a write error, and
 maybe record a bad block (then fail the device is writing the badblock
 record fails). Is that what were want?
Mainly to simplify the code. And I thought a normal discard should not fail.
If it fails, something is wrong, marked it as badblock maybe not bad.
 And of course resync/recovery will mess up the discarded sector 
information,
 so this isn't a complete solution for RAID1. But it is a reasonable start.
Yes, this is a mess. Looks impossible without ondisk format change at
first glance.

Thanks,
Shaohua

Re: [patch 0/7] Add TRIM support for raid linear/0/1/10

From: Mark Lord <hidden>
Date: 2012-03-17 18:15:06

On 12-03-13 10:47 PM, Shaohua Li wrote:
On 3/14/12 10:24 AM, NeilBrown wrote:
quoted
 On Mon, 12 Mar 2012 11:04:12 +0800 Shaohua Li [off-list ref] wrote:
..
quoted
 Also I wonder about handling failure in RAID1.
 I think the code will currently treat it like a write error, and
 maybe record a bad block (then fail the device is writing the badblock
 record fails). Is that what were want?
Mainly to simplify the code. And I thought a normal discard should not fail.
If it fails, something is wrong, marked it as badblock maybe not bad.
That sounds like a VERY bad idea.
Failures happen for lots of reasons,
but generic comm errors are not an excuse to suddenly mark sectors as bad.

Re: [patch 0/7] Add TRIM support for raid linear/0/1/10

From: Shaohua Li <shli@kernel.org>
Date: 2012-03-18 02:03:34

2012/3/18 Mark Lord [off-list ref]:
On 12-03-13 10:47 PM, Shaohua Li wrote:
quoted
On 3/14/12 10:24 AM, NeilBrown wrote:
quoted
 On Mon, 12 Mar 2012 11:04:12 +0800 Shaohua Li [off-list ref] wrote:
..
quoted
quoted
 Also I wonder about handling failure in RAID1.
 I think the code will currently treat it like a write error, and
 maybe record a bad block (then fail the device is writing the badblock
 record fails). Is that what were want?
Mainly to simplify the code. And I thought a normal discard should not fail.
If it fails, something is wrong, marked it as badblock maybe not bad.
That sounds like a VERY bad idea.
Failures happen for lots of reasons,
but generic comm errors are not an excuse to suddenly mark sectors as bad.
Not sure if I got it, but we treat discard similar like write. Did you
mean discard
request error is common?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help