aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c2
-rw-r--r--fs/btrfs/disk-io.c56
-rw-r--r--fs/btrfs/disk-io.h2
-rw-r--r--fs/btrfs/extent-tree.c4
-rw-r--r--fs/btrfs/extent_io.c49
-rw-r--r--fs/btrfs/extent_io.h7
-rw-r--r--fs/btrfs/inode.c66
-rw-r--r--fs/btrfs/tree-defrag.c7
-rw-r--r--fs/btrfs/volumes.c11
9 files changed, 155 insertions, 49 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 289d71d8653a..02e571e6ee62 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -379,7 +379,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
379 379
380 cur = btrfs_find_tree_block(root, blocknr, blocksize); 380 cur = btrfs_find_tree_block(root, blocknr, blocksize);
381 if (cur) 381 if (cur)
382 uptodate = btrfs_buffer_uptodate(cur); 382 uptodate = btrfs_buffer_uptodate(cur, gen);
383 else 383 else
384 uptodate = 0; 384 uptodate = 0;
385 if (!cur || !uptodate) { 385 if (!cur || !uptodate) {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index edee7a44f861..574b1245964e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -205,6 +205,33 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
205 return 0; 205 return 0;
206} 206}
207 207
208static int verify_parent_transid(struct extent_io_tree *io_tree,
209 struct extent_buffer *eb, u64 parent_transid)
210{
211 int ret;
212
213 if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
214 return 0;
215
216 lock_extent(io_tree, eb->start, eb->start + eb->len - 1, GFP_NOFS);
217 if (extent_buffer_uptodate(io_tree, eb) &&
218 btrfs_header_generation(eb) == parent_transid) {
219 ret = 0;
220 goto out;
221 }
222 printk("parent transid verify failed on %llu wanted %llu found %llu\n",
223 (unsigned long long)eb->start,
224 (unsigned long long)parent_transid,
225 (unsigned long long)btrfs_header_generation(eb));
226 ret = 1;
227out:
228 clear_extent_buffer_uptodate(io_tree, eb);
229 unlock_extent(io_tree, eb->start, eb->start + eb->len - 1,
230 GFP_NOFS);
231 return ret;
232
233}
234
208static int btree_read_extent_buffer_pages(struct btrfs_root *root, 235static int btree_read_extent_buffer_pages(struct btrfs_root *root,
209 struct extent_buffer *eb, 236 struct extent_buffer *eb,
210 u64 start, u64 parent_transid) 237 u64 start, u64 parent_transid)
@@ -218,7 +245,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
218 while (1) { 245 while (1) {
219 ret = read_extent_buffer_pages(io_tree, eb, start, 1, 246 ret = read_extent_buffer_pages(io_tree, eb, start, 1,
220 btree_get_extent, mirror_num); 247 btree_get_extent, mirror_num);
221 if (!ret) 248 if (!ret &&
249 !verify_parent_transid(io_tree, eb, parent_transid))
222 return ret; 250 return ret;
223 251
224 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, 252 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
@@ -330,6 +358,13 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
330 ret = -EIO; 358 ret = -EIO;
331 goto err; 359 goto err;
332 } 360 }
361 if (memcmp_extent_buffer(eb, root->fs_info->fsid,
362 (unsigned long)btrfs_header_fsid(eb),
363 BTRFS_FSID_SIZE)) {
364 printk("bad fsid on block %Lu\n", eb->start);
365 ret = -EIO;
366 goto err;
367 }
333 found_level = btrfs_header_level(eb); 368 found_level = btrfs_header_level(eb);
334 369
335 ret = csum_tree_block(root, eb, 1); 370 ret = csum_tree_block(root, eb, 1);
@@ -1363,7 +1398,9 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate)
1363 "I/O error on %s\n", 1398 "I/O error on %s\n",
1364 bdevname(bh->b_bdev, b)); 1399 bdevname(bh->b_bdev, b));
1365 } 1400 }
1366 set_buffer_write_io_error(bh); 1401 /* note, we dont' set_buffer_write_io_error because we have
1402 * our own ways of dealing with the IO errors
1403 */
1367 clear_buffer_uptodate(bh); 1404 clear_buffer_uptodate(bh);
1368 } 1405 }
1369 unlock_buffer(bh); 1406 unlock_buffer(bh);
@@ -1459,7 +1496,8 @@ int write_all_supers(struct btrfs_root *root)
1459 ret = submit_bh(WRITE, bh); 1496 ret = submit_bh(WRITE, bh);
1460 BUG_ON(ret); 1497 BUG_ON(ret);
1461 wait_on_buffer(bh); 1498 wait_on_buffer(bh);
1462 BUG_ON(!buffer_uptodate(bh)); 1499 if (!buffer_uptodate(bh))
1500 total_errors++;
1463 } else { 1501 } else {
1464 total_errors++; 1502 total_errors++;
1465 } 1503 }
@@ -1607,10 +1645,18 @@ int close_ctree(struct btrfs_root *root)
1607 return 0; 1645 return 0;
1608} 1646}
1609 1647
1610int btrfs_buffer_uptodate(struct extent_buffer *buf) 1648int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
1611{ 1649{
1650 int ret;
1612 struct inode *btree_inode = buf->first_page->mapping->host; 1651 struct inode *btree_inode = buf->first_page->mapping->host;
1613 return extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf); 1652
1653 ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf);
1654 if (!ret)
1655 return ret;
1656
1657 ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf,
1658 parent_transid);
1659 return !ret;
1614} 1660}
1615 1661
1616int btrfs_set_buffer_uptodate(struct extent_buffer *buf) 1662int btrfs_set_buffer_uptodate(struct extent_buffer *buf)
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index e29c895d5230..30d1ed293c25 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -56,7 +56,7 @@ int btrfs_insert_dev_radix(struct btrfs_root *root,
56void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); 56void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
57int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); 57int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root);
58void btrfs_mark_buffer_dirty(struct extent_buffer *buf); 58void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
59int btrfs_buffer_uptodate(struct extent_buffer *buf); 59int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid);
60int btrfs_set_buffer_uptodate(struct extent_buffer *buf); 60int btrfs_set_buffer_uptodate(struct extent_buffer *buf);
61int wait_on_tree_block_writeback(struct btrfs_root *root, 61int wait_on_tree_block_writeback(struct btrfs_root *root,
62 struct extent_buffer *buf); 62 struct extent_buffer *buf);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index db07dde4a870..605018c6045c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1366,7 +1366,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
1366 if (!pending) { 1366 if (!pending) {
1367 buf = btrfs_find_tree_block(root, bytenr, num_bytes); 1367 buf = btrfs_find_tree_block(root, bytenr, num_bytes);
1368 if (buf) { 1368 if (buf) {
1369 if (btrfs_buffer_uptodate(buf)) { 1369 if (btrfs_buffer_uptodate(buf, 0)) {
1370 u64 transid = 1370 u64 transid =
1371 root->fs_info->running_transaction->transid; 1371 root->fs_info->running_transaction->transid;
1372 u64 header_transid = 1372 u64 header_transid =
@@ -2151,7 +2151,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2151 continue; 2151 continue;
2152 } 2152 }
2153 next = btrfs_find_tree_block(root, bytenr, blocksize); 2153 next = btrfs_find_tree_block(root, bytenr, blocksize);
2154 if (!next || !btrfs_buffer_uptodate(next)) { 2154 if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
2155 free_extent_buffer(next); 2155 free_extent_buffer(next);
2156 reada_walk_down(root, cur, path->slots[*level]); 2156 reada_walk_down(root, cur, path->slots[*level]);
2157 2157
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index dd403b426ff5..2a3624adc0cf 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1366,7 +1366,7 @@ static int end_bio_extent_writepage(struct bio *bio,
1366 unsigned int bytes_done, int err) 1366 unsigned int bytes_done, int err)
1367#endif 1367#endif
1368{ 1368{
1369 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 1369 int uptodate = err == 0;
1370 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; 1370 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
1371 struct extent_state *state = bio->bi_private; 1371 struct extent_state *state = bio->bi_private;
1372 struct extent_io_tree *tree = state->tree; 1372 struct extent_io_tree *tree = state->tree;
@@ -1375,6 +1375,7 @@ static int end_bio_extent_writepage(struct bio *bio,
1375 u64 end; 1375 u64 end;
1376 u64 cur; 1376 u64 cur;
1377 int whole_page; 1377 int whole_page;
1378 int ret;
1378 unsigned long flags; 1379 unsigned long flags;
1379 1380
1380#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) 1381#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
@@ -1395,17 +1396,30 @@ static int end_bio_extent_writepage(struct bio *bio,
1395 if (--bvec >= bio->bi_io_vec) 1396 if (--bvec >= bio->bi_io_vec)
1396 prefetchw(&bvec->bv_page->flags); 1397 prefetchw(&bvec->bv_page->flags);
1397 1398
1399 if (tree->ops && tree->ops->writepage_end_io_hook) {
1400 ret = tree->ops->writepage_end_io_hook(page, start,
1401 end, state);
1402 if (ret)
1403 uptodate = 0;
1404 }
1405
1406 if (!uptodate && tree->ops &&
1407 tree->ops->writepage_io_failed_hook) {
1408 ret = tree->ops->writepage_io_failed_hook(bio, page,
1409 start, end, state);
1410 if (ret == 0) {
1411 state = NULL;
1412 uptodate = (err == 0);
1413 continue;
1414 }
1415 }
1416
1398 if (!uptodate) { 1417 if (!uptodate) {
1399 clear_extent_uptodate(tree, start, end, GFP_ATOMIC); 1418 clear_extent_uptodate(tree, start, end, GFP_ATOMIC);
1400 ClearPageUptodate(page); 1419 ClearPageUptodate(page);
1401 SetPageError(page); 1420 SetPageError(page);
1402 } 1421 }
1403 1422
1404 if (tree->ops && tree->ops->writepage_end_io_hook) {
1405 tree->ops->writepage_end_io_hook(page, start, end,
1406 state);
1407 }
1408
1409 /* 1423 /*
1410 * bios can get merged in funny ways, and so we need to 1424 * bios can get merged in funny ways, and so we need to
1411 * be careful with the state variable. We know the 1425 * be careful with the state variable. We know the
@@ -2073,9 +2087,9 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2073 } else { 2087 } else {
2074 ret = 0; 2088 ret = 0;
2075 } 2089 }
2076 if (ret) 2090 if (ret) {
2077 SetPageError(page); 2091 SetPageError(page);
2078 else { 2092 } else {
2079 unsigned long max_nr = end_index + 1; 2093 unsigned long max_nr = end_index + 1;
2080 set_range_writeback(tree, cur, cur + iosize - 1); 2094 set_range_writeback(tree, cur, cur + iosize - 1);
2081 if (!PageWriteback(page)) { 2095 if (!PageWriteback(page)) {
@@ -2948,6 +2962,25 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
2948} 2962}
2949EXPORT_SYMBOL(set_extent_buffer_dirty); 2963EXPORT_SYMBOL(set_extent_buffer_dirty);
2950 2964
2965int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
2966 struct extent_buffer *eb)
2967{
2968 unsigned long i;
2969 struct page *page;
2970 unsigned long num_pages;
2971
2972 num_pages = num_extent_pages(eb->start, eb->len);
2973 eb->flags &= ~EXTENT_UPTODATE;
2974
2975 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
2976 GFP_NOFS);
2977 for (i = 0; i < num_pages; i++) {
2978 page = extent_buffer_page(eb, i);
2979 ClearPageUptodate(page);
2980 }
2981 return 0;
2982}
2983
2951int set_extent_buffer_uptodate(struct extent_io_tree *tree, 2984int set_extent_buffer_uptodate(struct extent_io_tree *tree,
2952 struct extent_buffer *eb) 2985 struct extent_buffer *eb)
2953{ 2986{
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index e48346147514..f1960dafaa19 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -36,9 +36,12 @@ struct extent_io_ops {
36 int (*readpage_io_failed_hook)(struct bio *bio, struct page *page, 36 int (*readpage_io_failed_hook)(struct bio *bio, struct page *page,
37 u64 start, u64 end, 37 u64 start, u64 end,
38 struct extent_state *state); 38 struct extent_state *state);
39 int (*writepage_io_failed_hook)(struct bio *bio, struct page *page,
40 u64 start, u64 end,
41 struct extent_state *state);
39 int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end, 42 int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end,
40 struct extent_state *state); 43 struct extent_state *state);
41 void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, 44 int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,
42 struct extent_state *state); 45 struct extent_state *state);
43 int (*set_bit_hook)(struct inode *inode, u64 start, u64 end, 46 int (*set_bit_hook)(struct inode *inode, u64 start, u64 end,
44 unsigned long old, unsigned long bits); 47 unsigned long old, unsigned long bits);
@@ -212,6 +215,8 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
212 struct extent_buffer *eb); 215 struct extent_buffer *eb);
213int set_extent_buffer_uptodate(struct extent_io_tree *tree, 216int set_extent_buffer_uptodate(struct extent_io_tree *tree,
214 struct extent_buffer *eb); 217 struct extent_buffer *eb);
218int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
219 struct extent_buffer *eb);
215int extent_buffer_uptodate(struct extent_io_tree *tree, 220int extent_buffer_uptodate(struct extent_io_tree *tree,
216 struct extent_buffer *eb); 221 struct extent_buffer *eb);
217int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, 222int map_extent_buffer(struct extent_buffer *eb, unsigned long offset,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a492fd238c88..08760ff9bab7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -430,9 +430,9 @@ struct io_failure_record {
430 int last_mirror; 430 int last_mirror;
431}; 431};
432 432
433int btrfs_readpage_io_failed_hook(struct bio *failed_bio, 433int btrfs_io_failed_hook(struct bio *failed_bio,
434 struct page *page, u64 start, u64 end, 434 struct page *page, u64 start, u64 end,
435 struct extent_state *state) 435 struct extent_state *state)
436{ 436{
437 struct io_failure_record *failrec = NULL; 437 struct io_failure_record *failrec = NULL;
438 u64 private; 438 u64 private;
@@ -443,6 +443,7 @@ int btrfs_readpage_io_failed_hook(struct bio *failed_bio,
443 struct bio *bio; 443 struct bio *bio;
444 int num_copies; 444 int num_copies;
445 int ret; 445 int ret;
446 int rw;
446 u64 logical; 447 u64 logical;
447 448
448 ret = get_state_private(failure_tree, start, &private); 449 ret = get_state_private(failure_tree, start, &private);
@@ -505,7 +506,41 @@ int btrfs_readpage_io_failed_hook(struct bio *failed_bio,
505 bio->bi_bdev = failed_bio->bi_bdev; 506 bio->bi_bdev = failed_bio->bi_bdev;
506 bio->bi_size = 0; 507 bio->bi_size = 0;
507 bio_add_page(bio, page, failrec->len, start - page_offset(page)); 508 bio_add_page(bio, page, failrec->len, start - page_offset(page));
508 btrfs_submit_bio_hook(inode, READ, bio, failrec->last_mirror); 509 if (failed_bio->bi_rw & (1 << BIO_RW))
510 rw = WRITE;
511 else
512 rw = READ;
513
514 BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio,
515 failrec->last_mirror);
516 return 0;
517}
518
519int btrfs_clean_io_failures(struct inode *inode, u64 start)
520{
521 u64 private;
522 u64 private_failure;
523 struct io_failure_record *failure;
524 int ret;
525
526 private = 0;
527 if (count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private,
528 (u64)-1, 1, EXTENT_DIRTY)) {
529 ret = get_state_private(&BTRFS_I(inode)->io_failure_tree,
530 start, &private_failure);
531 if (ret == 0) {
532 failure = (struct io_failure_record *)(unsigned long)
533 private_failure;
534 set_state_private(&BTRFS_I(inode)->io_failure_tree,
535 failure->start, 0);
536 clear_extent_bits(&BTRFS_I(inode)->io_failure_tree,
537 failure->start,
538 failure->start + failure->len - 1,
539 EXTENT_DIRTY | EXTENT_LOCKED,
540 GFP_NOFS);
541 kfree(failure);
542 }
543 }
509 return 0; 544 return 0;
510} 545}
511 546
@@ -547,26 +582,7 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
547 /* if the io failure tree for this inode is non-empty, 582 /* if the io failure tree for this inode is non-empty,
548 * check to see if we've recovered from a failed IO 583 * check to see if we've recovered from a failed IO
549 */ 584 */
550 private = 0; 585 btrfs_clean_io_failures(inode, start);
551 if (count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private,
552 (u64)-1, 1, EXTENT_DIRTY)) {
553 u64 private_failure;
554 struct io_failure_record *failure;
555 ret = get_state_private(&BTRFS_I(inode)->io_failure_tree,
556 start, &private_failure);
557 if (ret == 0) {
558 failure = (struct io_failure_record *)(unsigned long)
559 private_failure;
560 set_state_private(&BTRFS_I(inode)->io_failure_tree,
561 failure->start, 0);
562 clear_extent_bits(&BTRFS_I(inode)->io_failure_tree,
563 failure->start,
564 failure->start + failure->len - 1,
565 EXTENT_DIRTY | EXTENT_LOCKED,
566 GFP_NOFS);
567 kfree(failure);
568 }
569 }
570 return 0; 586 return 0;
571 587
572zeroit: 588zeroit:
@@ -3657,7 +3673,7 @@ static struct extent_io_ops btrfs_extent_io_ops = {
3657 .merge_bio_hook = btrfs_merge_bio_hook, 3673 .merge_bio_hook = btrfs_merge_bio_hook,
3658 .readpage_io_hook = btrfs_readpage_io_hook, 3674 .readpage_io_hook = btrfs_readpage_io_hook,
3659 .readpage_end_io_hook = btrfs_readpage_end_io_hook, 3675 .readpage_end_io_hook = btrfs_readpage_end_io_hook,
3660 .readpage_io_failed_hook = btrfs_readpage_io_failed_hook, 3676 .readpage_io_failed_hook = btrfs_io_failed_hook,
3661 .set_bit_hook = btrfs_set_bit_hook, 3677 .set_bit_hook = btrfs_set_bit_hook,
3662 .clear_bit_hook = btrfs_clear_bit_hook, 3678 .clear_bit_hook = btrfs_clear_bit_hook,
3663}; 3679};
diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
index 5085e9e693b9..c02e2bf2f028 100644
--- a/fs/btrfs/tree-defrag.c
+++ b/fs/btrfs/tree-defrag.c
@@ -51,6 +51,7 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
51 struct extent_buffer *next; 51 struct extent_buffer *next;
52 struct extent_buffer *cur; 52 struct extent_buffer *cur;
53 u64 bytenr; 53 u64 bytenr;
54 u64 ptr_gen;
54 int ret = 0; 55 int ret = 0;
55 int is_extent = 0; 56 int is_extent = 0;
56 57
@@ -93,11 +94,12 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
93 break; 94 break;
94 } 95 }
95 bytenr = btrfs_node_blockptr(cur, path->slots[*level]); 96 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
97 ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
96 98
97 if (cache_only) { 99 if (cache_only) {
98 next = btrfs_find_tree_block(root, bytenr, 100 next = btrfs_find_tree_block(root, bytenr,
99 btrfs_level_size(root, *level - 1)); 101 btrfs_level_size(root, *level - 1));
100 if (!next || !btrfs_buffer_uptodate(next) || 102 if (!next || !btrfs_buffer_uptodate(next, ptr_gen) ||
101 !btrfs_buffer_defrag(next)) { 103 !btrfs_buffer_defrag(next)) {
102 free_extent_buffer(next); 104 free_extent_buffer(next);
103 path->slots[*level]++; 105 path->slots[*level]++;
@@ -106,8 +108,7 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
106 } else { 108 } else {
107 next = read_tree_block(root, bytenr, 109 next = read_tree_block(root, bytenr,
108 btrfs_level_size(root, *level - 1), 110 btrfs_level_size(root, *level - 1),
109 btrfs_node_ptr_generation(cur, 111 ptr_gen);
110 path->slots[*level]));
111 } 112 }
112 ret = btrfs_cow_block(trans, root, next, path->nodes[*level], 113 ret = btrfs_cow_block(trans, root, next, path->nodes[*level],
113 path->slots[*level], &next); 114 path->slots[*level], &next);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b5d7bd1915b4..5fc7fb481474 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1807,14 +1807,19 @@ static int end_bio_multi_stripe(struct bio *bio,
1807 if (atomic_dec_and_test(&multi->stripes_pending)) { 1807 if (atomic_dec_and_test(&multi->stripes_pending)) {
1808 bio->bi_private = multi->private; 1808 bio->bi_private = multi->private;
1809 bio->bi_end_io = multi->end_io; 1809 bio->bi_end_io = multi->end_io;
1810
1811 /* only send an error to the higher layers if it is 1810 /* only send an error to the higher layers if it is
1812 * beyond the tolerance of the multi-bio 1811 * beyond the tolerance of the multi-bio
1813 */ 1812 */
1814 if (atomic_read(&multi->error) > multi->max_errors) 1813 if (atomic_read(&multi->error) > multi->max_errors) {
1815 err = -EIO; 1814 err = -EIO;
1816 else 1815 } else if (err) {
1816 /*
1817 * this bio is actually up to date, we didn't
1818 * go over the max number of errors
1819 */
1820 set_bit(BIO_UPTODATE, &bio->bi_flags);
1817 err = 0; 1821 err = 0;
1822 }
1818 kfree(multi); 1823 kfree(multi);
1819 1824
1820#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) 1825#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)