aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-11-08 10:59:22 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:57 -0400
commit3ab2fb5a8cb003897016b6eb38ddad916226c1b2 (patch)
treedce5ac7ae586111c7e872193c09ced717b936549 /fs/btrfs/extent_map.c
parent856bf3e592f917e7d663cb7fa93e83fe795e8f4e (diff)
Btrfs: Add readpages support
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 754bc42c162..0077c6c1d9f 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -11,6 +11,7 @@
11#include <linux/swap.h> 11#include <linux/swap.h>
12#include <linux/version.h> 12#include <linux/version.h>
13#include <linux/writeback.h> 13#include <linux/writeback.h>
14#include <linux/pagevec.h>
14#include "extent_map.h" 15#include "extent_map.h"
15 16
16/* temporary define until extent_map moves out of btrfs */ 17/* temporary define until extent_map moves out of btrfs */
@@ -1503,7 +1504,7 @@ static int submit_extent_page(int rw, struct extent_map_tree *tree,
1503 size_t size, unsigned long offset, 1504 size_t size, unsigned long offset,
1504 struct block_device *bdev, 1505 struct block_device *bdev,
1505 struct bio **bio_ret, 1506 struct bio **bio_ret,
1506 int max_pages, 1507 unsigned long max_pages,
1507 bio_end_io_t end_io_func) 1508 bio_end_io_t end_io_func)
1508{ 1509{
1509 int ret = 0; 1510 int ret = 0;
@@ -1520,7 +1521,7 @@ static int submit_extent_page(int rw, struct extent_map_tree *tree,
1520 return 0; 1521 return 0;
1521 } 1522 }
1522 } 1523 }
1523 nr = min(max_pages, bio_get_nr_vecs(bdev)); 1524 nr = min_t(int, max_pages, bio_get_nr_vecs(bdev));
1524 bio = extent_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); 1525 bio = extent_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH);
1525 if (!bio) { 1526 if (!bio) {
1526 printk("failed to allocate bio nr %d\n", nr); 1527 printk("failed to allocate bio nr %d\n", nr);
@@ -1552,8 +1553,10 @@ void set_page_extent_mapped(struct page *page)
1552 * into the tree that are removed when the IO is done (by the end_io 1553 * into the tree that are removed when the IO is done (by the end_io
1553 * handlers) 1554 * handlers)
1554 */ 1555 */
1555int extent_read_full_page(struct extent_map_tree *tree, struct page *page, 1556static int __extent_read_full_page(struct extent_map_tree *tree,
1556 get_extent_t *get_extent) 1557 struct page *page,
1558 get_extent_t *get_extent,
1559 struct bio **bio)
1557{ 1560{
1558 struct inode *inode = page->mapping->host; 1561 struct inode *inode = page->mapping->host;
1559 u64 start = (u64)page->index << PAGE_CACHE_SHIFT; 1562 u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
@@ -1631,10 +1634,12 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
1631 cur + iosize - 1); 1634 cur + iosize - 1);
1632 } 1635 }
1633 if (!ret) { 1636 if (!ret) {
1637 unsigned long nr = (last_byte >> PAGE_CACHE_SHIFT) + 1;
1638 nr -= page->index;
1634 ret = submit_extent_page(READ, tree, page, 1639 ret = submit_extent_page(READ, tree, page,
1635 sector, iosize, page_offset, 1640 sector, iosize, page_offset,
1636 bdev, NULL, 1, 1641 bdev, bio, nr,
1637 end_bio_extent_readpage); 1642 end_bio_extent_readpage);
1638 } 1643 }
1639 if (ret) 1644 if (ret)
1640 SetPageError(page); 1645 SetPageError(page);
@@ -1649,6 +1654,18 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
1649 } 1654 }
1650 return 0; 1655 return 0;
1651} 1656}
1657
1658int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
1659 get_extent_t *get_extent)
1660{
1661 struct bio *bio = NULL;
1662 int ret;
1663
1664 ret = __extent_read_full_page(tree, page, get_extent, &bio);
1665 if (bio)
1666 submit_one_bio(READ, bio);
1667 return ret;
1668}
1652EXPORT_SYMBOL(extent_read_full_page); 1669EXPORT_SYMBOL(extent_read_full_page);
1653 1670
1654/* 1671/*
@@ -1836,6 +1853,45 @@ int extent_writepages(struct extent_map_tree *tree,
1836} 1853}
1837EXPORT_SYMBOL(extent_writepages); 1854EXPORT_SYMBOL(extent_writepages);
1838 1855
1856int extent_readpages(struct extent_map_tree *tree,
1857 struct address_space *mapping,
1858 struct list_head *pages, unsigned nr_pages,
1859 get_extent_t get_extent)
1860{
1861 struct bio *bio = NULL;
1862 unsigned page_idx;
1863 struct pagevec pvec;
1864
1865 pagevec_init(&pvec, 0);
1866 for (page_idx = 0; page_idx < nr_pages; page_idx++) {
1867 struct page *page = list_entry(pages->prev, struct page, lru);
1868
1869 prefetchw(&page->flags);
1870 list_del(&page->lru);
1871 /*
1872 * what we want to do here is call add_to_page_cache_lru,
1873 * but that isn't exported, so we reproduce it here
1874 */
1875 if (!add_to_page_cache(page, mapping,
1876 page->index, GFP_KERNEL)) {
1877
1878 /* open coding of lru_cache_add, also not exported */
1879 page_cache_get(page);
1880 if (!pagevec_add(&pvec, page))
1881 __pagevec_lru_add(&pvec);
1882 __extent_read_full_page(tree, page, get_extent, &bio);
1883 }
1884 page_cache_release(page);
1885 }
1886 if (pagevec_count(&pvec))
1887 __pagevec_lru_add(&pvec);
1888 BUG_ON(!list_empty(pages));
1889 if (bio)
1890 submit_one_bio(READ, bio);
1891 return 0;
1892}
1893EXPORT_SYMBOL(extent_readpages);
1894
1839/* 1895/*
1840 * basic invalidatepage code, this waits on any locked or writeback 1896 * basic invalidatepage code, this waits on any locked or writeback
1841 * ranges corresponding to the page, and then deletes any extent state 1897 * ranges corresponding to the page, and then deletes any extent state