aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bcache
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-04-22 17:44:24 -0400
committerKent Overstreet <koverstreet@google.com>2013-04-22 17:44:24 -0400
commita09ded8edf9ed4009930713e101249084cbcea5c (patch)
treee0a451f20434c8a0bfc28a36421d1b025be6dad5 /drivers/md/bcache
parent1545f13730be43278ce12f4af7e51b4dee5066a8 (diff)
bcache: Fix merge_bvec_fn usage for when it modifies the bvm
Stacked md devices reuse the bvm for the subordinate device, causing problems... Reported-by: Michael Balser <michael.balser@profitbricks.com> Signed-off-by: Kent Overstreet <koverstreet@google.com>
Diffstat (limited to 'drivers/md/bcache')
-rw-r--r--drivers/md/bcache/io.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index 5304eaab6cbe..48efd4dea645 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -163,13 +163,6 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
163 struct bio_vec *bv, *end = bio_iovec(bio) + 163 struct bio_vec *bv, *end = bio_iovec(bio) +
164 min_t(int, bio_segments(bio), max_segments); 164 min_t(int, bio_segments(bio), max_segments);
165 165
166 struct bvec_merge_data bvm = {
167 .bi_bdev = bio->bi_bdev,
168 .bi_sector = bio->bi_sector,
169 .bi_size = 0,
170 .bi_rw = bio->bi_rw,
171 };
172
173 if (bio->bi_rw & REQ_DISCARD) 166 if (bio->bi_rw & REQ_DISCARD)
174 return min(ret, q->limits.max_discard_sectors); 167 return min(ret, q->limits.max_discard_sectors);
175 168
@@ -178,12 +171,18 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
178 ret = 0; 171 ret = 0;
179 172
180 for (bv = bio_iovec(bio); bv < end; bv++) { 173 for (bv = bio_iovec(bio); bv < end; bv++) {
174 struct bvec_merge_data bvm = {
175 .bi_bdev = bio->bi_bdev,
176 .bi_sector = bio->bi_sector,
177 .bi_size = ret << 9,
178 .bi_rw = bio->bi_rw,
179 };
180
181 if (q->merge_bvec_fn && 181 if (q->merge_bvec_fn &&
182 q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len) 182 q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len)
183 break; 183 break;
184 184
185 ret += bv->bv_len >> 9; 185 ret += bv->bv_len >> 9;
186 bvm.bi_size += bv->bv_len;
187 } 186 }
188 } 187 }
189 188