aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2014-03-14 18:43:07 -0400
committerMike Snitzer <snitzer@redhat.com>2014-06-03 13:44:07 -0400
commit298eaa89b02e88dc9081f8761a957f7cd5e8b201 (patch)
tree19e9c438300cfee59abc6e499ab6bfaa872a9de5 /drivers/md
parent599cdf3bfbe21fe94f4416c9e54363b285c9532a (diff)
dm snapshot: do not split read bios sent to snapshot-origin target
Change the snapshot-origin target so that only write bios are split on chunk boundary. Read bios are passed unchanged to the underlying device, so they don't have to be split. Later, we could change the target so that it accepts a larger write bio if it spans an area that is completely covered by snapshot exceptions. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-snap.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 220a06bfe91b..e5a84c890e8f 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -2143,6 +2143,7 @@ static int origin_write_extent(struct dm_snapshot *merging_snap,
2143 2143
2144struct dm_origin { 2144struct dm_origin {
2145 struct dm_dev *dev; 2145 struct dm_dev *dev;
2146 unsigned split_boundary;
2146}; 2147};
2147 2148
2148/* 2149/*
@@ -2194,13 +2195,24 @@ static void origin_dtr(struct dm_target *ti)
2194static int origin_map(struct dm_target *ti, struct bio *bio) 2195static int origin_map(struct dm_target *ti, struct bio *bio)
2195{ 2196{
2196 struct dm_origin *o = ti->private; 2197 struct dm_origin *o = ti->private;
2198 unsigned available_sectors;
2199
2197 bio->bi_bdev = o->dev->bdev; 2200 bio->bi_bdev = o->dev->bdev;
2198 2201
2199 if (bio->bi_rw & REQ_FLUSH) 2202 if (unlikely(bio->bi_rw & REQ_FLUSH))
2203 return DM_MAPIO_REMAPPED;
2204
2205 if (bio_rw(bio) != WRITE)
2200 return DM_MAPIO_REMAPPED; 2206 return DM_MAPIO_REMAPPED;
2201 2207
2208 available_sectors = o->split_boundary -
2209 ((unsigned)bio->bi_iter.bi_sector & (o->split_boundary - 1));
2210
2211 if (bio_sectors(bio) > available_sectors)
2212 dm_accept_partial_bio(bio, available_sectors);
2213
2202 /* Only tell snapshots if this is a write */ 2214 /* Only tell snapshots if this is a write */
2203 return (bio_rw(bio) == WRITE) ? do_origin(o->dev, bio) : DM_MAPIO_REMAPPED; 2215 return do_origin(o->dev, bio);
2204} 2216}
2205 2217
2206/* 2218/*
@@ -2211,7 +2223,7 @@ static void origin_resume(struct dm_target *ti)
2211{ 2223{
2212 struct dm_origin *o = ti->private; 2224 struct dm_origin *o = ti->private;
2213 2225
2214 ti->max_io_len = get_origin_minimum_chunksize(o->dev->bdev); 2226 o->split_boundary = get_origin_minimum_chunksize(o->dev->bdev);
2215} 2227}
2216 2228
2217static void origin_status(struct dm_target *ti, status_type_t type, 2229static void origin_status(struct dm_target *ti, status_type_t type,