bcache: Fix merge_bvec_fn usage for when it modifies the bvm
authorKent Overstreet <koverstreet@google.com>
Mon, 22 Apr 2013 21:44:24 +0000 (14:44 -0700)
committerKent Overstreet <koverstreet@google.com>
Mon, 22 Apr 2013 21:44:24 +0000 (14:44 -0700)
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>
drivers/md/bcache/io.c

index 5304eaa..48efd4d 100644 (file)
@@ -163,13 +163,6 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
        struct bio_vec *bv, *end = bio_iovec(bio) +
                min_t(int, bio_segments(bio), max_segments);
 
-       struct bvec_merge_data bvm = {
-               .bi_bdev        = bio->bi_bdev,
-               .bi_sector      = bio->bi_sector,
-               .bi_size        = 0,
-               .bi_rw          = bio->bi_rw,
-       };
-
        if (bio->bi_rw & REQ_DISCARD)
                return min(ret, q->limits.max_discard_sectors);
 
@@ -178,12 +171,18 @@ static unsigned bch_bio_max_sectors(struct bio *bio)
                ret = 0;
 
                for (bv = bio_iovec(bio); bv < end; bv++) {
+                       struct bvec_merge_data bvm = {
+                               .bi_bdev        = bio->bi_bdev,
+                               .bi_sector      = bio->bi_sector,
+                               .bi_size        = ret << 9,
+                               .bi_rw          = bio->bi_rw,
+                       };
+
                        if (q->merge_bvec_fn &&
                            q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len)
                                break;
 
-                       ret             += bv->bv_len >> 9;
-                       bvm.bi_size     += bv->bv_len;
+                       ret += bv->bv_len >> 9;
                }
        }