This is analogous to commit 627a2d3c29427637f4c5d31ccc7fcbd8d312cd71
('md: deal with merge_bvec_fn in component devices better.'),
which does the same for md-devices at the top of the stack.  The
following explanation is taken from that commit.  Thanks to Neil Brown
<ne...@suse.de> for the advice.

If a component device has a merge_bvec_fn then as we never call it
we must ensure we never need to.  Currently this is done by setting
max_sector to 1 PAGE, however this does not stop a bio being created
with several sub-page iovecs that would violate the merge_bvec_fn.

So instead set max_segments to 1 and set the segment boundary to the
same as a page boundary to ensure there is only ever one single-page
segment of IO requested at a time.

This can particularly be an issue when 'xen' is used as it is
known to submit multiple small buffers in a single bio.

References: http://bugs.debian.org/604457
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
We've been carrying this in Debian for about 3 years and it's about time
it got reviewed...  It's basically Neil's work so should probably have
his sign-off as well.

Ben.

--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -536,13 +536,15 @@ int dm_set_device_limits(struct dm_target *ti, struct 
dm_dev *dev,
                       (unsigned long long) start << SECTOR_SHIFT);
 
        /*
-        * Check if merge fn is supported.
-        * If not we'll force DM to use PAGE_SIZE or
-        * smaller I/O, just to be safe.
+        * If we don't call merge_bvec_fn, we must never risk
+        * violating it, so limit max_phys_segments to 1 lying within
+        * a single page.
         */
-       if (dm_queue_merge_is_compulsory(q) && !ti->type->merge)
-               blk_limits_max_hw_sectors(limits,
-                                         (unsigned int) (PAGE_SIZE >> 9));
+       if (dm_queue_merge_is_compulsory(q) && !ti->type->merge) {
+               limits->max_segments = 1;
+               limits->seg_boundary_mask = PAGE_CACHE_SIZE - 1;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(dm_set_device_limits);

-- 
Ben Hutchings
The most exhausting thing in life is being insincere. - Anne Morrow Lindberg

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to