diff options
-rw-r--r-- | fs/btrfs/backref.c | 10 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 21 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 19 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 4 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 18 |
5 files changed, 59 insertions, 13 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 23e927b191c9..04b5b3093893 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -423,7 +423,10 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info, | |||
423 | BUG_ON(!ref->wanted_disk_byte); | 423 | BUG_ON(!ref->wanted_disk_byte); |
424 | eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte, | 424 | eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte, |
425 | fs_info->tree_root->leafsize, 0); | 425 | fs_info->tree_root->leafsize, 0); |
426 | BUG_ON(!eb); | 426 | if (!eb || !extent_buffer_uptodate(eb)) { |
427 | free_extent_buffer(eb); | ||
428 | return -EIO; | ||
429 | } | ||
427 | btrfs_tree_read_lock(eb); | 430 | btrfs_tree_read_lock(eb); |
428 | if (btrfs_header_level(eb) == 0) | 431 | if (btrfs_header_level(eb) == 0) |
429 | btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0); | 432 | btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0); |
@@ -913,7 +916,10 @@ again: | |||
913 | info_level); | 916 | info_level); |
914 | eb = read_tree_block(fs_info->extent_root, | 917 | eb = read_tree_block(fs_info->extent_root, |
915 | ref->parent, bsz, 0); | 918 | ref->parent, bsz, 0); |
916 | BUG_ON(!eb); | 919 | if (!eb || !extent_buffer_uptodate(eb)) { |
920 | free_extent_buffer(eb); | ||
921 | return -EIO; | ||
922 | } | ||
917 | ret = find_extent_in_eb(eb, bytenr, | 923 | ret = find_extent_in_eb(eb, bytenr, |
918 | *extent_item_pos, &eie); | 924 | *extent_item_pos, &eie); |
919 | ref->inode_list = eie; | 925 | ref->inode_list = eie; |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 566d99b51bef..2bc34408872d 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1281,7 +1281,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1281 | free_extent_buffer(eb_root); | 1281 | free_extent_buffer(eb_root); |
1282 | blocksize = btrfs_level_size(root, old_root->level); | 1282 | blocksize = btrfs_level_size(root, old_root->level); |
1283 | old = read_tree_block(root, logical, blocksize, 0); | 1283 | old = read_tree_block(root, logical, blocksize, 0); |
1284 | if (!old) { | 1284 | if (!old || !extent_buffer_uptodate(old)) { |
1285 | free_extent_buffer(old); | ||
1285 | pr_warn("btrfs: failed to read tree block %llu from get_old_root\n", | 1286 | pr_warn("btrfs: failed to read tree block %llu from get_old_root\n", |
1286 | logical); | 1287 | logical); |
1287 | WARN_ON(1); | 1288 | WARN_ON(1); |
@@ -1526,8 +1527,10 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
1526 | if (!cur) { | 1527 | if (!cur) { |
1527 | cur = read_tree_block(root, blocknr, | 1528 | cur = read_tree_block(root, blocknr, |
1528 | blocksize, gen); | 1529 | blocksize, gen); |
1529 | if (!cur) | 1530 | if (!cur || !extent_buffer_uptodate(cur)) { |
1531 | free_extent_buffer(cur); | ||
1530 | return -EIO; | 1532 | return -EIO; |
1533 | } | ||
1531 | } else if (!uptodate) { | 1534 | } else if (!uptodate) { |
1532 | err = btrfs_read_buffer(cur, gen); | 1535 | err = btrfs_read_buffer(cur, gen); |
1533 | if (err) { | 1536 | if (err) { |
@@ -1692,6 +1695,8 @@ static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root, | |||
1692 | struct extent_buffer *parent, int slot) | 1695 | struct extent_buffer *parent, int slot) |
1693 | { | 1696 | { |
1694 | int level = btrfs_header_level(parent); | 1697 | int level = btrfs_header_level(parent); |
1698 | struct extent_buffer *eb; | ||
1699 | |||
1695 | if (slot < 0) | 1700 | if (slot < 0) |
1696 | return NULL; | 1701 | return NULL; |
1697 | if (slot >= btrfs_header_nritems(parent)) | 1702 | if (slot >= btrfs_header_nritems(parent)) |
@@ -1699,9 +1704,15 @@ static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root, | |||
1699 | 1704 | ||
1700 | BUG_ON(level == 0); | 1705 | BUG_ON(level == 0); |
1701 | 1706 | ||
1702 | return read_tree_block(root, btrfs_node_blockptr(parent, slot), | 1707 | eb = read_tree_block(root, btrfs_node_blockptr(parent, slot), |
1703 | btrfs_level_size(root, level - 1), | 1708 | btrfs_level_size(root, level - 1), |
1704 | btrfs_node_ptr_generation(parent, slot)); | 1709 | btrfs_node_ptr_generation(parent, slot)); |
1710 | if (eb && !extent_buffer_uptodate(eb)) { | ||
1711 | free_extent_buffer(eb); | ||
1712 | eb = NULL; | ||
1713 | } | ||
1714 | |||
1715 | return eb; | ||
1705 | } | 1716 | } |
1706 | 1717 | ||
1707 | /* | 1718 | /* |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c7d8fb0dbff6..deb6e3d07281 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1496,6 +1496,14 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
1496 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 1496 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
1497 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 1497 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
1498 | blocksize, generation); | 1498 | blocksize, generation); |
1499 | if (!root->node || !extent_buffer_uptodate(root->node)) { | ||
1500 | ret = (!root->node) ? -ENOMEM : -EIO; | ||
1501 | |||
1502 | free_extent_buffer(root->node); | ||
1503 | kfree(root); | ||
1504 | return ERR_PTR(ret); | ||
1505 | } | ||
1506 | |||
1499 | root->commit_root = btrfs_root_node(root); | 1507 | root->commit_root = btrfs_root_node(root); |
1500 | BUG_ON(!root->node); /* -ENOMEM */ | 1508 | BUG_ON(!root->node); /* -ENOMEM */ |
1501 | out: | 1509 | out: |
@@ -2515,8 +2523,8 @@ int open_ctree(struct super_block *sb, | |||
2515 | chunk_root->node = read_tree_block(chunk_root, | 2523 | chunk_root->node = read_tree_block(chunk_root, |
2516 | btrfs_super_chunk_root(disk_super), | 2524 | btrfs_super_chunk_root(disk_super), |
2517 | blocksize, generation); | 2525 | blocksize, generation); |
2518 | BUG_ON(!chunk_root->node); /* -ENOMEM */ | 2526 | if (!chunk_root->node || |
2519 | if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) { | 2527 | !test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) { |
2520 | printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n", | 2528 | printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n", |
2521 | sb->s_id); | 2529 | sb->s_id); |
2522 | goto fail_tree_roots; | 2530 | goto fail_tree_roots; |
@@ -2701,6 +2709,13 @@ retry_root_backup: | |||
2701 | log_tree_root->node = read_tree_block(tree_root, bytenr, | 2709 | log_tree_root->node = read_tree_block(tree_root, bytenr, |
2702 | blocksize, | 2710 | blocksize, |
2703 | generation + 1); | 2711 | generation + 1); |
2712 | if (!log_tree_root->node || | ||
2713 | !extent_buffer_uptodate(log_tree_root->node)) { | ||
2714 | printk(KERN_ERR "btrfs: failed to read log tree\n"); | ||
2715 | free_extent_buffer(log_tree_root->node); | ||
2716 | kfree(log_tree_root); | ||
2717 | goto fail_trans_kthread; | ||
2718 | } | ||
2704 | /* returns with log_tree_root freed on success */ | 2719 | /* returns with log_tree_root freed on success */ |
2705 | ret = btrfs_recover_log_trees(log_tree_root); | 2720 | ret = btrfs_recover_log_trees(log_tree_root); |
2706 | if (ret) { | 2721 | if (ret) { |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 94bed61b799f..6526f1faf6c2 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -7087,8 +7087,10 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
7087 | if (reada && level == 1) | 7087 | if (reada && level == 1) |
7088 | reada_walk_down(trans, root, wc, path); | 7088 | reada_walk_down(trans, root, wc, path); |
7089 | next = read_tree_block(root, bytenr, blocksize, generation); | 7089 | next = read_tree_block(root, bytenr, blocksize, generation); |
7090 | if (!next) | 7090 | if (!next || !extent_buffer_uptodate(next)) { |
7091 | free_extent_buffer(next); | ||
7091 | return -EIO; | 7092 | return -EIO; |
7093 | } | ||
7092 | btrfs_tree_lock(next); | 7094 | btrfs_tree_lock(next); |
7093 | btrfs_set_lock_blocking(next); | 7095 | btrfs_set_lock_blocking(next); |
7094 | } | 7096 | } |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 208154986c4c..63cdd9246c70 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1771,7 +1771,11 @@ again: | |||
1771 | 1771 | ||
1772 | eb = read_tree_block(dest, old_bytenr, blocksize, | 1772 | eb = read_tree_block(dest, old_bytenr, blocksize, |
1773 | old_ptr_gen); | 1773 | old_ptr_gen); |
1774 | BUG_ON(!eb); | 1774 | if (!eb || !extent_buffer_uptodate(eb)) { |
1775 | ret = (!eb) ? -ENOMEM : -EIO; | ||
1776 | free_extent_buffer(eb); | ||
1777 | return ret; | ||
1778 | } | ||
1775 | btrfs_tree_lock(eb); | 1779 | btrfs_tree_lock(eb); |
1776 | if (cow) { | 1780 | if (cow) { |
1777 | ret = btrfs_cow_block(trans, dest, eb, parent, | 1781 | ret = btrfs_cow_block(trans, dest, eb, parent, |
@@ -1924,6 +1928,10 @@ int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path, | |||
1924 | bytenr = btrfs_node_blockptr(eb, path->slots[i]); | 1928 | bytenr = btrfs_node_blockptr(eb, path->slots[i]); |
1925 | blocksize = btrfs_level_size(root, i - 1); | 1929 | blocksize = btrfs_level_size(root, i - 1); |
1926 | eb = read_tree_block(root, bytenr, blocksize, ptr_gen); | 1930 | eb = read_tree_block(root, bytenr, blocksize, ptr_gen); |
1931 | if (!eb || !extent_buffer_uptodate(eb)) { | ||
1932 | free_extent_buffer(eb); | ||
1933 | return -EIO; | ||
1934 | } | ||
1927 | BUG_ON(btrfs_header_level(eb) != i - 1); | 1935 | BUG_ON(btrfs_header_level(eb) != i - 1); |
1928 | path->nodes[i - 1] = eb; | 1936 | path->nodes[i - 1] = eb; |
1929 | path->slots[i - 1] = 0; | 1937 | path->slots[i - 1] = 0; |
@@ -2601,7 +2609,8 @@ static int do_relocation(struct btrfs_trans_handle *trans, | |||
2601 | blocksize = btrfs_level_size(root, node->level); | 2609 | blocksize = btrfs_level_size(root, node->level); |
2602 | generation = btrfs_node_ptr_generation(upper->eb, slot); | 2610 | generation = btrfs_node_ptr_generation(upper->eb, slot); |
2603 | eb = read_tree_block(root, bytenr, blocksize, generation); | 2611 | eb = read_tree_block(root, bytenr, blocksize, generation); |
2604 | if (!eb) { | 2612 | if (!eb || !extent_buffer_uptodate(eb)) { |
2613 | free_extent_buffer(eb); | ||
2605 | err = -EIO; | 2614 | err = -EIO; |
2606 | goto next; | 2615 | goto next; |
2607 | } | 2616 | } |
@@ -2762,7 +2771,10 @@ static int get_tree_block_key(struct reloc_control *rc, | |||
2762 | BUG_ON(block->key_ready); | 2771 | BUG_ON(block->key_ready); |
2763 | eb = read_tree_block(rc->extent_root, block->bytenr, | 2772 | eb = read_tree_block(rc->extent_root, block->bytenr, |
2764 | block->key.objectid, block->key.offset); | 2773 | block->key.objectid, block->key.offset); |
2765 | BUG_ON(!eb); | 2774 | if (!eb || !extent_buffer_uptodate(eb)) { |
2775 | free_extent_buffer(eb); | ||
2776 | return -EIO; | ||
2777 | } | ||
2766 | WARN_ON(btrfs_header_level(eb) != block->level); | 2778 | WARN_ON(btrfs_header_level(eb) != block->level); |
2767 | if (block->level == 0) | 2779 | if (block->level == 0) |
2768 | btrfs_item_key_to_cpu(eb, &block->key, 0); | 2780 | btrfs_item_key_to_cpu(eb, &block->key, 0); |