diff options
| author | Kent Overstreet <koverstreet@google.com> | 2013-04-22 17:44:24 -0400 |
|---|---|---|
| committer | Kent Overstreet <koverstreet@google.com> | 2013-04-22 17:44:24 -0400 |
| commit | a09ded8edf9ed4009930713e101249084cbcea5c (patch) | |
| tree | e0a451f20434c8a0bfc28a36421d1b025be6dad5 | |
| parent | 1545f13730be43278ce12f4af7e51b4dee5066a8 (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>
| -rw-r--r-- | drivers/md/bcache/io.c | 17 |
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 | ||
