Refactor blkdev_pblk_* in preparation for async writes

This commit is contained in:
Tom Marshall 2019-10-09 13:19:21 -07:00
parent b675fe573a
commit 4499785fbb
1 changed files with 49 additions and 43 deletions

View File

@ -118,71 +118,77 @@ dm_target_pblk_size(struct dm_target* ti)
* data is a page address (obtained via __get_free_pages and friends). * data is a page address (obtained via __get_free_pages and friends).
**************************************/ **************************************/
static int static struct bio*
blkdev_pblk_io(struct block_device* dev, unsigned int op, u64 pblk, u32 count, void *data) blkdev_pblk_io_prepare(struct block_device* dev, unsigned int op, u64 pblk, u32 count, void *data)
{ {
int ret;
unsigned long data_addr; unsigned long data_addr;
struct bio *bio; struct bio* bio;
data_addr = (unsigned long)data; data_addr = (unsigned long)data;
BUG_ON(data_addr & (PAGE_SIZE-1));
if (data_addr & (PAGE_SIZE-1)) { BUG_ON(!virt_addr_valid(data));
printk(KERN_ERR " Not page aligned\n");
return -EINVAL;
}
if (!virt_addr_valid(data)) {
printk(KERN_ERR " Not valid address\n");
return -EINVAL;
}
bio = bio_alloc(GFP_KERNEL, count); bio = bio_alloc(GFP_KERNEL, count);
if (!bio) { if (!bio) {
printk(KERN_ERR "%s: out of memory\n", __func__); printk(KERN_ERR "%s: out of memory\n", __func__);
return -ENOMEM; return NULL;
} }
bio_set_dev(bio, dev); bio_set_dev(bio, dev);
bio->bi_iter.bi_sector = (pblk << (PBLK_SHIFT - SECTOR_SHIFT));
bio->bi_opf = op; bio->bi_opf = op;
bio->bi_iter.bi_sector = (pblk << (PBLK_SHIFT - SECTOR_SHIFT));
while (count--) { while (count--) {
struct page *page = virt_to_page(data); struct page *page = virt_to_page(data);
if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
printk(KERN_ERR "%s: cannot add page to bio\n", __func__); BUG();
bio_put(bio);
return -EINVAL;
} }
data = (u8*)data + PAGE_SIZE; data = (u8*)data + PAGE_SIZE;
} }
/* return bio;
* 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;
}
bio_put(bio);
return ret;
} }
static int static int
blkdev_pblk_read(struct block_device* dev, u64 pblk, u32 count, void *data) blkdev_pblk_read(struct block_device* dev, u64 pblk, u32 count, void *data)
{ {
return blkdev_pblk_io(dev, REQ_OP_READ, pblk, count, 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;
}
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;
} }
static int static int
blkdev_pblk_write(struct block_device* dev, u64 pblk, u32 count, void *data) 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;
} }
/************************************** /**************************************