aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-09 16:28:12 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:01 -0400
commitf188591e987e21b6f7f8864c66a02858b95b530e (patch)
tree996f04b7c8d1e8a626b123e7a2a217992d705c60 /fs/btrfs/extent_io.c
parent22c599485b1fdd95e4476a4752596a6cf6c6629a (diff)
Btrfs: Retry metadata reads in the face of checksum failures
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index cfc383c17a3a..2f159375c878 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1546,7 +1546,7 @@ static int end_bio_extent_readpage(struct bio *bio,
1546 !(state->state & EXTENT_LOCKED)) 1546 !(state->state & EXTENT_LOCKED))
1547 state = NULL; 1547 state = NULL;
1548 } 1548 }
1549 if (!state) { 1549 if (!state && uptodate) {
1550 spin_unlock_irqrestore(&tree->lock, flags); 1550 spin_unlock_irqrestore(&tree->lock, flags);
1551 set_extent_uptodate(tree, start, end, 1551 set_extent_uptodate(tree, start, end,
1552 GFP_ATOMIC); 1552 GFP_ATOMIC);
@@ -1567,8 +1567,10 @@ static int end_bio_extent_readpage(struct bio *bio,
1567 } else { 1567 } else {
1568 state = NULL; 1568 state = NULL;
1569 } 1569 }
1570 set_state_cb(tree, clear, EXTENT_UPTODATE); 1570 if (uptodate) {
1571 clear->state |= EXTENT_UPTODATE; 1571 set_state_cb(tree, clear, EXTENT_UPTODATE);
1572 clear->state |= EXTENT_UPTODATE;
1573 }
1572 clear_state_bit(tree, clear, EXTENT_LOCKED, 1574 clear_state_bit(tree, clear, EXTENT_LOCKED,
1573 1, 0); 1575 1, 0);
1574 if (cur == start) 1576 if (cur == start)
@@ -1685,7 +1687,7 @@ extent_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
1685 return bio; 1687 return bio;
1686} 1688}
1687 1689
1688static int submit_one_bio(int rw, struct bio *bio) 1690static int submit_one_bio(int rw, struct bio *bio, int mirror_num)
1689{ 1691{
1690 u64 maxsector; 1692 u64 maxsector;
1691 int ret = 0; 1693 int ret = 0;
@@ -1722,7 +1724,8 @@ static int submit_one_bio(int rw, struct bio *bio)
1722 WARN_ON(1); 1724 WARN_ON(1);
1723 } 1725 }
1724 if (tree->ops && tree->ops->submit_bio_hook) 1726 if (tree->ops && tree->ops->submit_bio_hook)
1725 tree->ops->submit_bio_hook(page->mapping->host, rw, bio); 1727 tree->ops->submit_bio_hook(page->mapping->host, rw, bio,
1728 mirror_num);
1726 else 1729 else
1727 submit_bio(rw, bio); 1730 submit_bio(rw, bio);
1728 if (bio_flagged(bio, BIO_EOPNOTSUPP)) 1731 if (bio_flagged(bio, BIO_EOPNOTSUPP))
@@ -1737,7 +1740,8 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
1737 struct block_device *bdev, 1740 struct block_device *bdev,
1738 struct bio **bio_ret, 1741 struct bio **bio_ret,
1739 unsigned long max_pages, 1742 unsigned long max_pages,
1740 bio_end_io_t end_io_func) 1743 bio_end_io_t end_io_func,
1744 int mirror_num)
1741{ 1745{
1742 int ret = 0; 1746 int ret = 0;
1743 struct bio *bio; 1747 struct bio *bio;
@@ -1749,7 +1753,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
1749 (tree->ops && tree->ops->merge_bio_hook && 1753 (tree->ops && tree->ops->merge_bio_hook &&
1750 tree->ops->merge_bio_hook(page, offset, size, bio)) || 1754 tree->ops->merge_bio_hook(page, offset, size, bio)) ||
1751 bio_add_page(bio, page, size, offset) < size) { 1755 bio_add_page(bio, page, size, offset) < size) {
1752 ret = submit_one_bio(rw, bio); 1756 ret = submit_one_bio(rw, bio, mirror_num);
1753 bio = NULL; 1757 bio = NULL;
1754 } else { 1758 } else {
1755 return 0; 1759 return 0;
@@ -1769,7 +1773,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree,
1769 if (bio_ret) { 1773 if (bio_ret) {
1770 *bio_ret = bio; 1774 *bio_ret = bio;
1771 } else { 1775 } else {
1772 ret = submit_one_bio(rw, bio); 1776 ret = submit_one_bio(rw, bio, mirror_num);
1773 } 1777 }
1774 1778
1775 return ret; 1779 return ret;
@@ -1798,7 +1802,7 @@ void set_page_extent_head(struct page *page, unsigned long len)
1798static int __extent_read_full_page(struct extent_io_tree *tree, 1802static int __extent_read_full_page(struct extent_io_tree *tree,
1799 struct page *page, 1803 struct page *page,
1800 get_extent_t *get_extent, 1804 get_extent_t *get_extent,
1801 struct bio **bio) 1805 struct bio **bio, int mirror_num)
1802{ 1806{
1803 struct inode *inode = page->mapping->host; 1807 struct inode *inode = page->mapping->host;
1804 u64 start = (u64)page->index << PAGE_CACHE_SHIFT; 1808 u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
@@ -1901,7 +1905,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree,
1901 ret = submit_extent_page(READ, tree, page, 1905 ret = submit_extent_page(READ, tree, page,
1902 sector, iosize, page_offset, 1906 sector, iosize, page_offset,
1903 bdev, bio, nr, 1907 bdev, bio, nr,
1904 end_bio_extent_readpage); 1908 end_bio_extent_readpage, mirror_num);
1905 } 1909 }
1906 if (ret) 1910 if (ret)
1907 SetPageError(page); 1911 SetPageError(page);
@@ -1923,9 +1927,9 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
1923 struct bio *bio = NULL; 1927 struct bio *bio = NULL;
1924 int ret; 1928 int ret;
1925 1929
1926 ret = __extent_read_full_page(tree, page, get_extent, &bio); 1930 ret = __extent_read_full_page(tree, page, get_extent, &bio, 0);
1927 if (bio) 1931 if (bio)
1928 submit_one_bio(READ, bio); 1932 submit_one_bio(READ, bio, 0);
1929 return ret; 1933 return ret;
1930} 1934}
1931EXPORT_SYMBOL(extent_read_full_page); 1935EXPORT_SYMBOL(extent_read_full_page);
@@ -2077,7 +2081,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2077 ret = submit_extent_page(WRITE, tree, page, sector, 2081 ret = submit_extent_page(WRITE, tree, page, sector,
2078 iosize, page_offset, bdev, 2082 iosize, page_offset, bdev,
2079 &epd->bio, max_nr, 2083 &epd->bio, max_nr,
2080 end_bio_extent_writepage); 2084 end_bio_extent_writepage, 0);
2081 if (ret) 2085 if (ret)
2082 SetPageError(page); 2086 SetPageError(page);
2083 } 2087 }
@@ -2244,7 +2248,7 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page,
2244 2248
2245 write_cache_pages(mapping, &wbc_writepages, __extent_writepage, &epd); 2249 write_cache_pages(mapping, &wbc_writepages, __extent_writepage, &epd);
2246 if (epd.bio) { 2250 if (epd.bio) {
2247 submit_one_bio(WRITE, epd.bio); 2251 submit_one_bio(WRITE, epd.bio, 0);
2248 } 2252 }
2249 return ret; 2253 return ret;
2250} 2254}
@@ -2265,7 +2269,7 @@ int extent_writepages(struct extent_io_tree *tree,
2265 2269
2266 ret = write_cache_pages(mapping, wbc, __extent_writepage, &epd); 2270 ret = write_cache_pages(mapping, wbc, __extent_writepage, &epd);
2267 if (epd.bio) { 2271 if (epd.bio) {
2268 submit_one_bio(WRITE, epd.bio); 2272 submit_one_bio(WRITE, epd.bio, 0);
2269 } 2273 }
2270 return ret; 2274 return ret;
2271} 2275}
@@ -2297,7 +2301,8 @@ int extent_readpages(struct extent_io_tree *tree,
2297 page_cache_get(page); 2301 page_cache_get(page);
2298 if (!pagevec_add(&pvec, page)) 2302 if (!pagevec_add(&pvec, page))
2299 __pagevec_lru_add(&pvec); 2303 __pagevec_lru_add(&pvec);
2300 __extent_read_full_page(tree, page, get_extent, &bio); 2304 __extent_read_full_page(tree, page, get_extent,
2305 &bio, 0);
2301 } 2306 }
2302 page_cache_release(page); 2307 page_cache_release(page);
2303 } 2308 }
@@ -2305,7 +2310,7 @@ int extent_readpages(struct extent_io_tree *tree,
2305 __pagevec_lru_add(&pvec); 2310 __pagevec_lru_add(&pvec);
2306 BUG_ON(!list_empty(pages)); 2311 BUG_ON(!list_empty(pages));
2307 if (bio) 2312 if (bio)
2308 submit_one_bio(READ, bio); 2313 submit_one_bio(READ, bio, 0);
2309 return 0; 2314 return 0;
2310} 2315}
2311EXPORT_SYMBOL(extent_readpages); 2316EXPORT_SYMBOL(extent_readpages);
@@ -2430,7 +2435,7 @@ int extent_prepare_write(struct extent_io_tree *tree,
2430 ret = submit_extent_page(READ, tree, page, 2435 ret = submit_extent_page(READ, tree, page,
2431 sector, iosize, page_offset, em->bdev, 2436 sector, iosize, page_offset, em->bdev,
2432 NULL, 1, 2437 NULL, 1,
2433 end_bio_extent_preparewrite); 2438 end_bio_extent_preparewrite, 0);
2434 iocount++; 2439 iocount++;
2435 block_start = block_start + iosize; 2440 block_start = block_start + iosize;
2436 } else { 2441 } else {
@@ -2696,6 +2701,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
2696 mark_page_accessed(page0); 2701 mark_page_accessed(page0);
2697 set_page_extent_mapped(page0); 2702 set_page_extent_mapped(page0);
2698 set_page_extent_head(page0, len); 2703 set_page_extent_head(page0, len);
2704 uptodate = PageUptodate(page0);
2699 } else { 2705 } else {
2700 i = 0; 2706 i = 0;
2701 } 2707 }
@@ -3006,7 +3012,7 @@ EXPORT_SYMBOL(extent_buffer_uptodate);
3006int read_extent_buffer_pages(struct extent_io_tree *tree, 3012int read_extent_buffer_pages(struct extent_io_tree *tree,
3007 struct extent_buffer *eb, 3013 struct extent_buffer *eb,
3008 u64 start, int wait, 3014 u64 start, int wait,
3009 get_extent_t *get_extent) 3015 get_extent_t *get_extent, int mirror_num)
3010{ 3016{
3011 unsigned long i; 3017 unsigned long i;
3012 unsigned long start_i; 3018 unsigned long start_i;
@@ -3062,8 +3068,10 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3062 if (!PageUptodate(page)) { 3068 if (!PageUptodate(page)) {
3063 if (start_i == 0) 3069 if (start_i == 0)
3064 inc_all_pages = 1; 3070 inc_all_pages = 1;
3071 ClearPageError(page);
3065 err = __extent_read_full_page(tree, page, 3072 err = __extent_read_full_page(tree, page,
3066 get_extent, &bio); 3073 get_extent, &bio,
3074 mirror_num);
3067 if (err) { 3075 if (err) {
3068 ret = err; 3076 ret = err;
3069 } 3077 }
@@ -3073,7 +3081,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
3073 } 3081 }
3074 3082
3075 if (bio) 3083 if (bio)
3076 submit_one_bio(READ, bio); 3084 submit_one_bio(READ, bio, mirror_num);
3077 3085
3078 if (ret || !wait) { 3086 if (ret || !wait) {
3079 return ret; 3087 return ret;