diff options
author | Prasad Joshi <prasadjoshi.linux@gmail.com> | 2012-07-23 10:32:11 +0530 |
---|---|---|
committer | Prasad Joshi <prasadjoshi.linux@gmail.com> | 2012-07-23 10:32:11 +0530 |
commit | 9f0bbd8ca7905fcc0602c038013b095322fec939 (patch) | |
tree | d35de1ee5a475adc9d9e55432ff0ddb271343096 | |
parent | 41b93bc1ee7e7276db698dd66afa7b740cda517a (diff) | |
download | linux-9f0bbd8ca7905fcc0602c038013b095322fec939.tar.gz linux-9f0bbd8ca7905fcc0602c038013b095322fec939.tar.bz2 linux-9f0bbd8ca7905fcc0602c038013b095322fec939.zip |
logfs: query block device for number of pages to send with bio
The block device driver puts a limit on maximum number of pages that
can be sent with the bio. Not all block devices can handle
BIO_MAX_PAGES number of pages in bio. Specifically the virtio-blk
diriver limits it to 126. When the LogFS file system was excersized in
KVM, the following bug from do_virtblk_request() was observed
static void do_virtblk_request(struct request_queue *q)
{
....
....
while ((req = blk_peek_request(q)) != NULL) {
BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
....
....
}
....
}
The patch fixes the problem by querring the maximum number of pages in
bio allowed from block device driver and then using those many pages
during submit_bio.
Signed-off-by: Prasad Joshi <prasadjoshi.linux@gmail.com>
-rw-r--r-- | fs/logfs/dev_bdev.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index ea29df36893d..e784a217b500 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -96,12 +96,11 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, struct address_space *mapping = super->s_mapping_inode->i_mapping; struct bio *bio; struct page *page; - struct request_queue *q = bdev_get_queue(sb->s_bdev); - unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); + unsigned int max_pages; int i; - if (max_pages > BIO_MAX_PAGES) - max_pages = BIO_MAX_PAGES; + max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev)); + bio = bio_alloc(GFP_NOFS, max_pages); BUG_ON(!bio); @@ -191,12 +190,11 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index, { struct logfs_super *super = logfs_super(sb); struct bio *bio; - struct request_queue *q = bdev_get_queue(sb->s_bdev); - unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); + unsigned int max_pages; int i; - if (max_pages > BIO_MAX_PAGES) - max_pages = BIO_MAX_PAGES; + max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev)); + bio = bio_alloc(GFP_NOFS, max_pages); BUG_ON(!bio); |