|
@@ -287,7 +287,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
|
|
|
unsigned num_bvecs;
|
|
|
sector_t remaining = where->count;
|
|
|
struct request_queue *q = bdev_get_queue(where->bdev);
|
|
|
- sector_t discard_sectors;
|
|
|
+ unsigned short logical_block_size = queue_logical_block_size(q);
|
|
|
+ sector_t num_sectors;
|
|
|
|
|
|
/*
|
|
|
* where->count may be zero if rw holds a flush and we need to
|
|
@@ -297,7 +298,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
|
|
|
/*
|
|
|
* Allocate a suitably sized-bio.
|
|
|
*/
|
|
|
- if (rw & REQ_DISCARD)
|
|
|
+ if ((rw & REQ_DISCARD) || (rw & REQ_WRITE_SAME))
|
|
|
num_bvecs = 1;
|
|
|
else
|
|
|
num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev),
|
|
@@ -310,9 +311,21 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
|
|
|
store_io_and_region_in_bio(bio, io, region);
|
|
|
|
|
|
if (rw & REQ_DISCARD) {
|
|
|
- discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
|
|
|
- bio->bi_size = discard_sectors << SECTOR_SHIFT;
|
|
|
- remaining -= discard_sectors;
|
|
|
+ num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
|
|
|
+ bio->bi_size = num_sectors << SECTOR_SHIFT;
|
|
|
+ remaining -= num_sectors;
|
|
|
+ } else if (rw & REQ_WRITE_SAME) {
|
|
|
+ /*
|
|
|
+ * WRITE SAME only uses a single page.
|
|
|
+ */
|
|
|
+ dp->get_page(dp, &page, &len, &offset);
|
|
|
+ bio_add_page(bio, page, logical_block_size, offset);
|
|
|
+ num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining);
|
|
|
+ bio->bi_size = num_sectors << SECTOR_SHIFT;
|
|
|
+
|
|
|
+ offset = 0;
|
|
|
+ remaining -= num_sectors;
|
|
|
+ dp->next_page(dp);
|
|
|
} else while (remaining) {
|
|
|
/*
|
|
|
* Try and add as many pages as possible.
|