aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2012-04-16 09:42:26 -0400
committerDavid Sterba <dsterba@suse.cz>2012-04-18 13:22:30 -0400
commit5cf1ab56133ad7b712673c071b439d4a555a2d1e (patch)
treec7b301296750707f47487f508398f1baec81f48b /fs/btrfs/disk-io.c
parent48d282326b3ce5f435835f5fb0e3231c399f4f9a (diff)
Btrfs: always store the mirror we read the eb from
A user reported a panic where we were trying to fix a bad mirror but the mirror number we were giving was 0, which is invalid. This is because we don't do the transid verification until after the read, so as far as the read code is concerned the read was a success. So instead store the mirror we read from so that if there is some failure post read we know which mirror to try next and which mirror needs to be fixed if we find a good copy of the block. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b9866f27ebd7..d0c969beaad4 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -383,17 +383,16 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
383 if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) 383 if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags))
384 break; 384 break;
385 385
386 if (!failed_mirror) {
387 failed = 1;
388 printk(KERN_ERR "failed mirror was %d\n", eb->failed_mirror);
389 failed_mirror = eb->failed_mirror;
390 }
391
392 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, 386 num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
393 eb->start, eb->len); 387 eb->start, eb->len);
394 if (num_copies == 1) 388 if (num_copies == 1)
395 break; 389 break;
396 390
391 if (!failed_mirror) {
392 failed = 1;
393 failed_mirror = eb->read_mirror;
394 }
395
397 mirror_num++; 396 mirror_num++;
398 if (mirror_num == failed_mirror) 397 if (mirror_num == failed_mirror)
399 mirror_num++; 398 mirror_num++;
@@ -564,7 +563,7 @@ struct extent_buffer *find_eb_for_page(struct extent_io_tree *tree,
564} 563}
565 564
566static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, 565static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
567 struct extent_state *state) 566 struct extent_state *state, int mirror)
568{ 567{
569 struct extent_io_tree *tree; 568 struct extent_io_tree *tree;
570 u64 found_start; 569 u64 found_start;
@@ -589,6 +588,7 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
589 if (!reads_done) 588 if (!reads_done)
590 goto err; 589 goto err;
591 590
591 eb->read_mirror = mirror;
592 if (test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) { 592 if (test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) {
593 ret = -EIO; 593 ret = -EIO;
594 goto err; 594 goto err;
@@ -652,7 +652,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
652 652
653 eb = (struct extent_buffer *)page->private; 653 eb = (struct extent_buffer *)page->private;
654 set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); 654 set_bit(EXTENT_BUFFER_IOERR, &eb->bflags);
655 eb->failed_mirror = failed_mirror; 655 eb->read_mirror = failed_mirror;
656 if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) 656 if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags))
657 btree_readahead_hook(root, eb, eb->start, -EIO); 657 btree_readahead_hook(root, eb, eb->start, -EIO);
658 return -EIO; /* we fixed nothing */ 658 return -EIO; /* we fixed nothing */