aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-io.c
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2012-04-24 21:45:20 -0700
committerJP Abgrall <jpa@google.com>2012-04-24 21:45:20 -0700
commit10add970b62d2276541af9e5fb0581d6d8434db4 (patch)
treeafd79e8507c5fa243c044a6963072b6a6d0f059b /drivers/md/dm-io.c
parent9cea9c804af57f8538dc910e24c407c81e496e51 (diff)
parent66510aa1148e3457e7d46e0a2582dac7c591b95d (diff)
downloadkernel_samsung_crespo-10add970b62d2276541af9e5fb0581d6d8434db4.zip
kernel_samsung_crespo-10add970b62d2276541af9e5fb0581d6d8434db4.tar.gz
kernel_samsung_crespo-10add970b62d2276541af9e5fb0581d6d8434db4.tar.bz2
Merge remote-tracking branch 'common/android-3.0' into android-samsung-30-wip-mergedown
* common/android-3.0: (1178 commits) cpufreq: interactive: remove unused target_validate_time_in_idle cpufreq: interactive: Boost frequency on touchscreen input cpufreq: Separate speed target revalidate time and initial set time cpufreq: interactive: based hispeed bump on target freq, not actual cpufreq: interactive: adjust code and documentation to match cpufreq: interactive: configurable delay before raising above hispeed sync: add poll support sw_sync: add fill_driver_data support sync: add ioctl to get fence data sw_sync: add debug support sync: add debugfs support sync: add timestamps to sync_pts sw_sync: add cpu based sync driver sync: Add synchronization framework Linux 3.0.28 Bluetooth: Fix l2cap conn failures for ssp devices TOMOYO: Fix mount flags checking order. iommu/amd: Make sure IOMMU interrupts are re-enabled on resume cred: copy_process() should clear child->replacement_session_keyring ASoC: ak4642: fixup: mute needs +1 step ... Conflicts: mm/compaction.c Change-Id: I3dc59225d2435eddbed0c639155179e580891ac8 Signed-off-by: JP Abgrall <jpa@google.com>
Diffstat (limited to 'drivers/md/dm-io.c')
-rw-r--r--drivers/md/dm-io.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index ad2eba4..ea5dd28 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -296,6 +296,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
unsigned offset;
unsigned num_bvecs;
sector_t remaining = where->count;
+ struct request_queue *q = bdev_get_queue(where->bdev);
+ sector_t discard_sectors;
/*
* where->count may be zero if rw holds a flush and we need to
@@ -305,9 +307,12 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
/*
* Allocate a suitably sized-bio.
*/
- num_bvecs = dm_sector_div_up(remaining,
- (PAGE_SIZE >> SECTOR_SHIFT));
- num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs);
+ if (rw & REQ_DISCARD)
+ num_bvecs = 1;
+ else
+ num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev),
+ dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT)));
+
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
bio->bi_sector = where->sector + (where->count - remaining);
bio->bi_bdev = where->bdev;
@@ -315,10 +320,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
bio->bi_destructor = dm_bio_destructor;
store_io_and_region_in_bio(bio, io, region);
- /*
- * Try and add as many pages as possible.
- */
- while (remaining) {
+ 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;
+ } else while (remaining) {
+ /*
+ * Try and add as many pages as possible.
+ */
dp->get_page(dp, &page, &len, &offset);
len = min(len, to_bytes(remaining));
if (!bio_add_page(bio, page, len, offset))