aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2009-06-22 05:12:14 -0400
committerAlasdair G Kergon <agk@redhat.com>2009-06-22 05:12:14 -0400
commit8cbeb67ad50f7d68e5e83be2cb2284de8f9c03b5 (patch)
tree4fd4a467c06441ad7c07211b386c786062aa2aeb
parent53b351f972a882ea8b6cdb19602535f1057c884a (diff)
dm: avoid unsupported spanning of md stripe boundaries
A bio that has two or more vector entries, size less than or equal to page size, that crosses a stripe boundary of an underlying md device is accepted by device mapper (it conforms to all its limits) but not by the underlying device. The fix is: If device mapper selects the one-page maximum request size, it also needs to set its own q->merge_bvec_fn to reject any bios with multiple vector entries that span more pages. The problem was discovered in the following scenario: * MD - RAID-0 * LV on the top of it (raid1, snapshot or striped with chunk size/stripe larger than RAID-0 stripe) * one of the logical volumes is exported to xen domU * inside xen domU it is partitioned, the key point is that the partition must be unaligned on page boundary (fdisk normally aligns the partition to 63 sectors which will trigger it) * install the system on the partitioned disk in domU This causes I/O failures in dom0. Reference: https://bugzilla.redhat.com/show_bug.cgi?id=223947 Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r--drivers/md/dm.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index f1db689667ea..59806e67a175 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -925,6 +925,16 @@ static int dm_merge_bvec(struct request_queue *q,
925 */ 925 */
926 if (max_size && ti->type->merge) 926 if (max_size && ti->type->merge)
927 max_size = ti->type->merge(ti, bvm, biovec, max_size); 927 max_size = ti->type->merge(ti, bvm, biovec, max_size);
928 /*
929 * If the target doesn't support merge method and some of the devices
930 * provided their merge_bvec method (we know this by looking at
931 * queue_max_hw_sectors), then we can't allow bios with multiple vector
932 * entries. So always set max_size to 0, and the code below allows
933 * just one page.
934 */
935 else if (queue_max_hw_sectors(q) <= PAGE_SIZE >> 9)
936
937 max_size = 0;
928 938
929out_table: 939out_table:
930 dm_table_put(map); 940 dm_table_put(map);