aboutsummaryrefslogtreecommitdiffstats
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
parent22c599485b1fdd95e4476a4752596a6cf6c6629a (diff)
Btrfs: Retry metadata reads in the face of checksum failures
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c11
-rw-r--r--fs/btrfs/disk-io.c72
-rw-r--r--fs/btrfs/extent_io.c50
-rw-r--r--fs/btrfs/extent_io.h5
-rw-r--r--fs/btrfs/inode.c7
-rw-r--r--fs/btrfs/volumes.c39
-rw-r--r--fs/btrfs/volumes.h6
7 files changed, 138 insertions, 52 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index efce173a935c..ff4e9c6859d1 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -569,7 +569,16 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
569static int noinline check_block(struct btrfs_root *root, 569static int noinline check_block(struct btrfs_root *root,
570 struct btrfs_path *path, int level) 570 struct btrfs_path *path, int level)
571{ 571{
572 return 0; 572 u64 found_start;
573 if (btrfs_header_level(path->nodes[level]) != level)
574 printk("warning: bad level %Lu wanted %d found %d\n",
575 path->nodes[level]->start, level,
576 btrfs_header_level(path->nodes[level]));
577 found_start = btrfs_header_bytenr(path->nodes[level]);
578 if (found_start != path->nodes[level]->start) {
579 printk("warning: bad bytentr %Lu found %Lu\n",
580 path->nodes[level]->start, found_start);
581 }
573#if 0 582#if 0
574 struct extent_buffer *buf = path->nodes[level]; 583 struct extent_buffer *buf = path->nodes[level];
575 584
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 94ff87d0eae4..59bdf0474be3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -156,7 +156,6 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
156 memcpy(&found, result, BTRFS_CRC32_SIZE); 156 memcpy(&found, result, BTRFS_CRC32_SIZE);
157 157
158 read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE); 158 read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE);
159 WARN_ON(1);
160 printk("btrfs: %s checksum verify failed on %llu " 159 printk("btrfs: %s checksum verify failed on %llu "
161 "wanted %X found %X from_this_trans %d " 160 "wanted %X found %X from_this_trans %d "
162 "level %d\n", 161 "level %d\n",
@@ -171,6 +170,40 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
171 return 0; 170 return 0;
172} 171}
173 172
173static int btree_read_extent_buffer_pages(struct btrfs_root *root,
174 struct extent_buffer *eb,
175 u64 start)
176{
177 struct extent_io_tree *io_tree;
178 int ret;
179 int num_copies = 0;
180 int mirror_num = 0;
181
182 io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
183 while (1) {
184 ret = read_extent_buffer_pages(io_tree, eb, start, 1,
185 btree_get_extent, mirror_num);
186 if (!ret) {
187 if (mirror_num)
188printk("good read %Lu mirror %d total %d\n", eb->start, mirror_num, num_copies);
189 return ret;
190 }
191 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
192 eb->start, eb->len);
193printk("failed to read %Lu mirror %d total %d\n", eb->start, mirror_num, num_copies);
194 if (num_copies == 1) {
195printk("reading %Lu failed only one copy\n", eb->start);
196 return ret;
197 }
198 mirror_num++;
199 if (mirror_num > num_copies) {
200printk("bailing at mirror %d of %d\n", mirror_num, num_copies);
201 return ret;
202 }
203 }
204printk("read extent buffer page last\n");
205 return -EIO;
206}
174 207
175int csum_dirty_buffer(struct btrfs_root *root, struct page *page) 208int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
176{ 209{
@@ -180,6 +213,8 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
180 int found_level; 213 int found_level;
181 unsigned long len; 214 unsigned long len;
182 struct extent_buffer *eb; 215 struct extent_buffer *eb;
216 int ret;
217
183 tree = &BTRFS_I(page->mapping->host)->io_tree; 218 tree = &BTRFS_I(page->mapping->host)->io_tree;
184 219
185 if (page->private == EXTENT_PAGE_PRIVATE) 220 if (page->private == EXTENT_PAGE_PRIVATE)
@@ -191,8 +226,8 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
191 WARN_ON(1); 226 WARN_ON(1);
192 } 227 }
193 eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); 228 eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS);
194 read_extent_buffer_pages(tree, eb, start + PAGE_CACHE_SIZE, 1, 229 ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE);
195 btree_get_extent); 230 BUG_ON(ret);
196 btrfs_clear_buffer_defrag(eb); 231 btrfs_clear_buffer_defrag(eb);
197 found_start = btrfs_header_bytenr(eb); 232 found_start = btrfs_header_bytenr(eb);
198 if (found_start != start) { 233 if (found_start != start) {
@@ -240,7 +275,7 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
240 unsigned long len; 275 unsigned long len;
241 struct extent_buffer *eb; 276 struct extent_buffer *eb;
242 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; 277 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
243 int ret; 278 int ret = 0;
244 279
245 tree = &BTRFS_I(page->mapping->host)->io_tree; 280 tree = &BTRFS_I(page->mapping->host)->io_tree;
246 if (page->private == EXTENT_PAGE_PRIVATE) 281 if (page->private == EXTENT_PAGE_PRIVATE)
@@ -252,25 +287,26 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
252 WARN_ON(1); 287 WARN_ON(1);
253 } 288 }
254 eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); 289 eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS);
255 read_extent_buffer_pages(tree, eb, start + PAGE_CACHE_SIZE, 1, 290
256 btree_get_extent);
257 btrfs_clear_buffer_defrag(eb); 291 btrfs_clear_buffer_defrag(eb);
258 found_start = btrfs_header_bytenr(eb); 292 found_start = btrfs_header_bytenr(eb);
259 if (found_start != start) { 293 if (found_start != start) {
260 printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", 294printk("bad start on %Lu found %Lu\n", eb->start, found_start);
261 start, found_start, len); 295 ret = -EIO;
262 WARN_ON(1);
263 goto err; 296 goto err;
264 } 297 }
265 if (eb->first_page != page) { 298 if (eb->first_page != page) {
266 printk("bad first page %lu %lu\n", eb->first_page->index, 299 printk("bad first page %lu %lu\n", eb->first_page->index,
267 page->index); 300 page->index);
268 WARN_ON(1); 301 WARN_ON(1);
302 ret = -EIO;
269 goto err; 303 goto err;
270 } 304 }
271 found_level = btrfs_header_level(eb); 305 found_level = btrfs_header_level(eb);
272 306
273 ret = csum_tree_block(root, eb, 1); 307 ret = csum_tree_block(root, eb, 1);
308 if (ret)
309 ret = -EIO;
274 310
275 end = min_t(u64, eb->len, PAGE_CACHE_SIZE); 311 end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
276 end = eb->start + end - 1; 312 end = eb->start + end - 1;
@@ -278,7 +314,7 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
278err: 314err:
279 free_extent_buffer(eb); 315 free_extent_buffer(eb);
280out: 316out:
281 return 0; 317 return ret;
282} 318}
283 319
284#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23) 320#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
@@ -329,7 +365,8 @@ int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
329 return 0; 365 return 0;
330} 366}
331 367
332static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio) 368static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
369 int mirror_num)
333{ 370{
334 struct btrfs_root *root = BTRFS_I(inode)->root; 371 struct btrfs_root *root = BTRFS_I(inode)->root;
335 u64 offset; 372 u64 offset;
@@ -338,7 +375,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio)
338 offset = bio->bi_sector << 9; 375 offset = bio->bi_sector << 9;
339 376
340 if (rw & (1 << BIO_RW)) { 377 if (rw & (1 << BIO_RW)) {
341 return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio); 378 return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num);
342 } 379 }
343 380
344 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 1); 381 ret = btrfs_bio_wq_end_io(root->fs_info, bio, 1);
@@ -349,7 +386,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio)
349 submit_bio(rw, bio); 386 submit_bio(rw, bio);
350 return 0; 387 return 0;
351 } 388 }
352 return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio); 389 return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num);
353} 390}
354 391
355static int btree_writepage(struct page *page, struct writeback_control *wbc) 392static int btree_writepage(struct page *page, struct writeback_control *wbc)
@@ -459,7 +496,7 @@ int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize)
459 if (!buf) 496 if (!buf)
460 return 0; 497 return 0;
461 read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, 498 read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
462 buf, 0, 0, btree_get_extent); 499 buf, 0, 0, btree_get_extent, 0);
463 free_extent_buffer(buf); 500 free_extent_buffer(buf);
464 return ret; 501 return ret;
465} 502}
@@ -522,8 +559,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
522 if (!buf) 559 if (!buf)
523 return NULL; 560 return NULL;
524 561
525 ret = read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, buf, 0, 562 ret = btree_read_extent_buffer_pages(root, buf, 0);
526 1, btree_get_extent);
527 563
528 if (ret == 0) { 564 if (ret == 0) {
529 buf->flags |= EXTENT_UPTODATE; 565 buf->flags |= EXTENT_UPTODATE;
@@ -1366,10 +1402,8 @@ int btrfs_clear_buffer_defrag(struct extent_buffer *buf)
1366int btrfs_read_buffer(struct extent_buffer *buf) 1402int btrfs_read_buffer(struct extent_buffer *buf)
1367{ 1403{
1368 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; 1404 struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
1369 struct inode *btree_inode = root->fs_info->btree_inode;
1370 int ret; 1405 int ret;
1371 ret = read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, 1406 ret = btree_read_extent_buffer_pages(root, buf, 0);
1372 buf, 0, 1, btree_get_extent);
1373 if (ret == 0) { 1407 if (ret == 0) {
1374 buf->flags |= EXTENT_UPTODATE; 1408 buf->flags |= EXTENT_UPTODATE;
1375 } 1409 }
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;
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 9d2991d1d3ce..8d6b8a14cc30 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -27,7 +27,8 @@ struct extent_state;
27struct extent_io_ops { 27struct extent_io_ops {
28 int (*fill_delalloc)(struct inode *inode, u64 start, u64 end); 28 int (*fill_delalloc)(struct inode *inode, u64 start, u64 end);
29 int (*writepage_io_hook)(struct page *page, u64 start, u64 end); 29 int (*writepage_io_hook)(struct page *page, u64 start, u64 end);
30 int (*submit_bio_hook)(struct inode *inode, int rw, struct bio *bio); 30 int (*submit_bio_hook)(struct inode *inode, int rw, struct bio *bio,
31 int mirror_num);
31 int (*merge_bio_hook)(struct page *page, unsigned long offset, 32 int (*merge_bio_hook)(struct page *page, unsigned long offset,
32 size_t size, struct bio *bio); 33 size_t size, struct bio *bio);
33 int (*readpage_io_hook)(struct page *page, u64 start, u64 end); 34 int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
@@ -172,7 +173,7 @@ struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
172void free_extent_buffer(struct extent_buffer *eb); 173void free_extent_buffer(struct extent_buffer *eb);
173int read_extent_buffer_pages(struct extent_io_tree *tree, 174int read_extent_buffer_pages(struct extent_io_tree *tree,
174 struct extent_buffer *eb, u64 start, int wait, 175 struct extent_buffer *eb, u64 start, int wait,
175 get_extent_t *get_extent); 176 get_extent_t *get_extent, int mirror_num);
176 177
177static inline void extent_buffer_get(struct extent_buffer *eb) 178static inline void extent_buffer_get(struct extent_buffer *eb)
178{ 179{
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e1ef1acdb350..8c2d5d036bd6 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -314,7 +314,7 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
314 map_tree = &root->fs_info->mapping_tree; 314 map_tree = &root->fs_info->mapping_tree;
315 map_length = length; 315 map_length = length;
316 ret = btrfs_map_block(map_tree, READ, logical, 316 ret = btrfs_map_block(map_tree, READ, logical,
317 &map_length, NULL); 317 &map_length, NULL, 0);
318 318
319 if (map_length < length + size) { 319 if (map_length < length + size) {
320 return 1; 320 return 1;
@@ -322,7 +322,8 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
322 return 0; 322 return 0;
323} 323}
324 324
325int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio) 325int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
326 int mirror_num)
326{ 327{
327 struct btrfs_root *root = BTRFS_I(inode)->root; 328 struct btrfs_root *root = BTRFS_I(inode)->root;
328 struct btrfs_trans_handle *trans; 329 struct btrfs_trans_handle *trans;
@@ -347,7 +348,7 @@ int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio)
347 BUG_ON(ret); 348 BUG_ON(ret);
348 mutex_unlock(&root->fs_info->fs_mutex); 349 mutex_unlock(&root->fs_info->fs_mutex);
349mapit: 350mapit:
350 return btrfs_map_bio(root, rw, bio); 351 return btrfs_map_bio(root, rw, bio, mirror_num);
351} 352}
352 353
353int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) 354int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 008d3640e8c2..3b927f698320 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -788,9 +788,31 @@ void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree)
788 } 788 }
789} 789}
790 790
791int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len)
792{
793 struct extent_map *em;
794 struct map_lookup *map;
795 struct extent_map_tree *em_tree = &map_tree->map_tree;
796 int ret;
797
798 spin_lock(&em_tree->lock);
799 em = lookup_extent_mapping(em_tree, logical, len);
800 BUG_ON(!em);
801
802 BUG_ON(em->start > logical || em->start + em->len < logical);
803 map = (struct map_lookup *)em->bdev;
804 if (map->type & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1))
805 ret = map->num_stripes;
806 else
807 ret = 1;
808 free_extent_map(em);
809 spin_unlock(&em_tree->lock);
810 return ret;
811}
812
791int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 813int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
792 u64 logical, u64 *length, 814 u64 logical, u64 *length,
793 struct btrfs_multi_bio **multi_ret) 815 struct btrfs_multi_bio **multi_ret, int mirror_num)
794{ 816{
795 struct extent_map *em; 817 struct extent_map *em;
796 struct map_lookup *map; 818 struct map_lookup *map;
@@ -822,6 +844,9 @@ again:
822 map = (struct map_lookup *)em->bdev; 844 map = (struct map_lookup *)em->bdev;
823 offset = logical - em->start; 845 offset = logical - em->start;
824 846
847 if (mirror_num > map->num_stripes)
848 mirror_num = 0;
849
825 /* if our multi bio struct is too small, back off and try again */ 850 /* if our multi bio struct is too small, back off and try again */
826 if (multi_ret && (rw & (1 << BIO_RW)) && 851 if (multi_ret && (rw & (1 << BIO_RW)) &&
827 stripes_allocated < map->num_stripes && 852 stripes_allocated < map->num_stripes &&
@@ -862,7 +887,9 @@ again:
862 if (map->type & BTRFS_BLOCK_GROUP_RAID1) { 887 if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
863 if (rw & (1 << BIO_RW)) 888 if (rw & (1 << BIO_RW))
864 multi->num_stripes = map->num_stripes; 889 multi->num_stripes = map->num_stripes;
865 else { 890 else if (mirror_num) {
891 stripe_index = mirror_num - 1;
892 } else {
866 int i; 893 int i;
867 u64 least = (u64)-1; 894 u64 least = (u64)-1;
868 struct btrfs_device *cur; 895 struct btrfs_device *cur;
@@ -880,6 +907,8 @@ again:
880 } else if (map->type & BTRFS_BLOCK_GROUP_DUP) { 907 } else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
881 if (rw & (1 << BIO_RW)) 908 if (rw & (1 << BIO_RW))
882 multi->num_stripes = map->num_stripes; 909 multi->num_stripes = map->num_stripes;
910 else if (mirror_num)
911 stripe_index = mirror_num - 1;
883 } else { 912 } else {
884 /* 913 /*
885 * after this do_div call, stripe_nr is the number of stripes 914 * after this do_div call, stripe_nr is the number of stripes
@@ -938,7 +967,8 @@ static int end_bio_multi_stripe(struct bio *bio,
938#endif 967#endif
939} 968}
940 969
941int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio) 970int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
971 int mirror_num)
942{ 972{
943 struct btrfs_mapping_tree *map_tree; 973 struct btrfs_mapping_tree *map_tree;
944 struct btrfs_device *dev; 974 struct btrfs_device *dev;
@@ -960,7 +990,8 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
960 map_tree = &root->fs_info->mapping_tree; 990 map_tree = &root->fs_info->mapping_tree;
961 map_length = length; 991 map_length = length;
962 992
963 ret = btrfs_map_block(map_tree, rw, logical, &map_length, &multi); 993 ret = btrfs_map_block(map_tree, rw, logical, &map_length, &multi,
994 mirror_num);
964 BUG_ON(ret); 995 BUG_ON(ret);
965 996
966 total_devs = multi->num_stripes; 997 total_devs = multi->num_stripes;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 10ca0104750c..3d5d0a9cb827 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -93,7 +93,7 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
93 u64 owner, u64 num_bytes, u64 *start); 93 u64 owner, u64 num_bytes, u64 *start);
94int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 94int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
95 u64 logical, u64 *length, 95 u64 logical, u64 *length,
96 struct btrfs_multi_bio **multi_ret); 96 struct btrfs_multi_bio **multi_ret, int mirror_num);
97int btrfs_read_sys_array(struct btrfs_root *root); 97int btrfs_read_sys_array(struct btrfs_root *root);
98int btrfs_read_chunk_tree(struct btrfs_root *root); 98int btrfs_read_chunk_tree(struct btrfs_root *root);
99int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, 99int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
@@ -101,7 +101,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
101 u64 *num_bytes, u64 type); 101 u64 *num_bytes, u64 type);
102void btrfs_mapping_init(struct btrfs_mapping_tree *tree); 102void btrfs_mapping_init(struct btrfs_mapping_tree *tree);
103void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree); 103void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree);
104int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio); 104int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
105 int mirror_num);
105int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf); 106int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf);
106int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, 107int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
107 int flags, void *holder); 108 int flags, void *holder);
@@ -112,4 +113,5 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
112 struct btrfs_root *root, 113 struct btrfs_root *root,
113 struct btrfs_device *device); 114 struct btrfs_device *device);
114int btrfs_cleanup_fs_uuids(void); 115int btrfs_cleanup_fs_uuids(void);
116int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len);
115#endif 117#endif