diff --git a/dm-compress/dm-compress.c b/dm-compress/dm-compress.c index 2fb4af6..9f8734f 100644 --- a/dm-compress/dm-compress.c +++ b/dm-compress/dm-compress.c @@ -118,71 +118,77 @@ dm_target_pblk_size(struct dm_target* ti) * data is a page address (obtained via __get_free_pages and friends). **************************************/ -static int -blkdev_pblk_io(struct block_device* dev, unsigned int op, u64 pblk, u32 count, void *data) +static struct bio* +blkdev_pblk_io_prepare(struct block_device* dev, unsigned int op, u64 pblk, u32 count, void *data) { - int ret; unsigned long data_addr; - struct bio *bio; + struct bio* bio; data_addr = (unsigned long)data; - - if (data_addr & (PAGE_SIZE-1)) { - printk(KERN_ERR " Not page aligned\n"); - return -EINVAL; - } - - if (!virt_addr_valid(data)) { - printk(KERN_ERR " Not valid address\n"); - return -EINVAL; - } + BUG_ON(data_addr & (PAGE_SIZE-1)); + BUG_ON(!virt_addr_valid(data)); bio = bio_alloc(GFP_KERNEL, count); + if (!bio) { + printk(KERN_ERR "%s: out of memory\n", __func__); + return NULL; + } + bio_set_dev(bio, dev); + bio->bi_opf = op; + + bio->bi_iter.bi_sector = (pblk << (PBLK_SHIFT - SECTOR_SHIFT)); + while (count--) { + struct page *page = virt_to_page(data); + if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { + BUG(); + } + data = (u8*)data + PAGE_SIZE; + } + + return bio; +} + +static int +blkdev_pblk_read(struct block_device* dev, u64 pblk, u32 count, void *data) +{ + int ret; + struct bio* bio; + + bio = blkdev_pblk_io_prepare(dev, REQ_OP_READ, pblk, count, data); if (!bio) { printk(KERN_ERR "%s: out of memory\n", __func__); return -ENOMEM; } - bio_set_dev(bio, dev); - bio->bi_iter.bi_sector = (pblk << (PBLK_SHIFT - SECTOR_SHIFT)); - bio->bi_opf = op; - - while (count--) { - struct page *page = virt_to_page(data); - if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { - printk(KERN_ERR "%s: cannot add page to bio\n", __func__); - bio_put(bio); - return -EINVAL; - } - data = (u8*)data + PAGE_SIZE; - } - - /* - * XXX: We would like to make writes asychronous, but submit_bio() does - * not return a meaningful status. - */ ret = submit_bio_wait(bio); if (ret != 0) { - printk(KERN_ERR "%s: submit_bio failed\n", __func__); - bio_put(bio); - return ret; + printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret); } - bio_put(bio); return ret; } -static int -blkdev_pblk_read(struct block_device* dev, u64 pblk, u32 count, void *data) -{ - return blkdev_pblk_io(dev, REQ_OP_READ, pblk, count, data); -} - static int blkdev_pblk_write(struct block_device* dev, u64 pblk, u32 count, void *data) { - return blkdev_pblk_io(dev, REQ_OP_WRITE, pblk, count, data); + int ret; + struct bio* bio; + + bio = blkdev_pblk_io_prepare(dev, REQ_OP_WRITE, pblk, count, data); + if (!bio) { + printk(KERN_ERR "%s: out of memory\n", __func__); + return -ENOMEM; + } + + /* XXX: Make writes asychronous. */ + ret = submit_bio_wait(bio); + if (ret != 0) { + printk(KERN_ERR "%s: submit_bio_wait failed: %d\n", __func__, ret); + } + bio_put(bio); + + return ret; } /**************************************