Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2005-01-20 18:27:36 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-20 18:27:36 -0800
commit88835ba226fef3096c3b53f6d62acf1a7c589f35 (patch)
tree4f2e88c5562366c063217a0cfc8f20b44152d0ea
parent6aba8f35bd088935bebd109218ef0f287a1cdc9c (diff)
[PATCH] Fix md using bio on stack with bio clones
If md resides on top of a driver using bio_clone() (such as dm), it will oops the kernel due to md submitting a botched bio that has a veclist but doesn't have bio->bi_max_vecs set. Signed-off-by: Jens Axboe <axboe@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/md.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5e59c814ef48..30ff0af37d95 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -332,29 +332,26 @@ static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
static int sync_page_io(struct block_device *bdev, sector_t sector, int size,
struct page *page, int rw)
{
- struct bio bio;
- struct bio_vec vec;
+ struct bio *bio = bio_alloc(GFP_KERNEL, 1);
struct completion event;
+ int ret;
+
+ bio_get(bio);
rw |= (1 << BIO_RW_SYNC);
- bio_init(&bio);
- bio.bi_io_vec = &vec;
- vec.bv_page = page;
- vec.bv_len = size;
- vec.bv_offset = 0;
- bio.bi_vcnt = 1;
- bio.bi_idx = 0;
- bio.bi_size = size;
- bio.bi_bdev = bdev;
- bio.bi_sector = sector;
+ bio->bi_bdev = bdev;
+ bio->bi_sector = sector;
+ bio_add_page(bio, page, size, 0);
init_completion(&event);
- bio.bi_private = &event;
- bio.bi_end_io = bi_complete;
- submit_bio(rw, &bio);
+ bio->bi_private = &event;
+ bio->bi_end_io = bi_complete;
+ submit_bio(rw, bio);
wait_for_completion(&event);
- return test_bit(BIO_UPTODATE, &bio.bi_flags);
+ ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
+ bio_put(bio);
+ return ret;
}
static int read_disk_sb(mdk_rdev_t * rdev)