aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2015-05-25 05:30:15 -0400
committerChris Mason <clm@fb.com>2015-06-03 07:03:08 -0400
commit64c043de466d5746e7ca306dab9d418cd871cefc (patch)
treefcce36cbfdc022f24b5b847152d6b17c967a1b64
parent8635eda91ee11690bd8f73b2504ee19431fd6380 (diff)
Btrfs: fix up read_tree_block to return proper error
The return value of read_tree_block() can confuse callers as it always returns NULL for either -ENOMEM or -EIO, so it's likely that callers parse it to a wrong error, for instance, in btrfs_read_tree_root(). This fixes the above issue. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/backref.c9
-rw-r--r--fs/btrfs/ctree.c16
-rw-r--r--fs/btrfs/disk-io.c28
-rw-r--r--fs/btrfs/extent-tree.c11
-rw-r--r--fs/btrfs/relocation.c19
5 files changed, 54 insertions, 29 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 614aaa1969bd..679dc97354be 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -491,7 +491,9 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info,
491 BUG_ON(!ref->wanted_disk_byte); 491 BUG_ON(!ref->wanted_disk_byte);
492 eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte, 492 eb = read_tree_block(fs_info->tree_root, ref->wanted_disk_byte,
493 0); 493 0);
494 if (!eb || !extent_buffer_uptodate(eb)) { 494 if (IS_ERR(eb)) {
495 return PTR_ERR(eb);
496 } else if (!extent_buffer_uptodate(eb)) {
495 free_extent_buffer(eb); 497 free_extent_buffer(eb);
496 return -EIO; 498 return -EIO;
497 } 499 }
@@ -1034,7 +1036,10 @@ again:
1034 1036
1035 eb = read_tree_block(fs_info->extent_root, 1037 eb = read_tree_block(fs_info->extent_root,
1036 ref->parent, 0); 1038 ref->parent, 0);
1037 if (!eb || !extent_buffer_uptodate(eb)) { 1039 if (IS_ERR(eb)) {
1040 ret = PTR_ERR(eb);
1041 goto out;
1042 } else if (!extent_buffer_uptodate(eb)) {
1038 free_extent_buffer(eb); 1043 free_extent_buffer(eb);
1039 ret = -EIO; 1044 ret = -EIO;
1040 goto out; 1045 goto out;
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 0f11ebc92f02..54114b4887dd 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1439,8 +1439,9 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
1439 btrfs_tree_read_unlock(eb_root); 1439 btrfs_tree_read_unlock(eb_root);
1440 free_extent_buffer(eb_root); 1440 free_extent_buffer(eb_root);
1441 old = read_tree_block(root, logical, 0); 1441 old = read_tree_block(root, logical, 0);
1442 if (WARN_ON(!old || !extent_buffer_uptodate(old))) { 1442 if (WARN_ON(IS_ERR(old) || !extent_buffer_uptodate(old))) {
1443 free_extent_buffer(old); 1443 if (!IS_ERR(old))
1444 free_extent_buffer(old);
1444 btrfs_warn(root->fs_info, 1445 btrfs_warn(root->fs_info,
1445 "failed to read tree block %llu from get_old_root", logical); 1446 "failed to read tree block %llu from get_old_root", logical);
1446 } else { 1447 } else {
@@ -1685,7 +1686,9 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
1685 if (!cur || !uptodate) { 1686 if (!cur || !uptodate) {
1686 if (!cur) { 1687 if (!cur) {
1687 cur = read_tree_block(root, blocknr, gen); 1688 cur = read_tree_block(root, blocknr, gen);
1688 if (!cur || !extent_buffer_uptodate(cur)) { 1689 if (IS_ERR(cur)) {
1690 return PTR_ERR(cur);
1691 } else if (!extent_buffer_uptodate(cur)) {
1689 free_extent_buffer(cur); 1692 free_extent_buffer(cur);
1690 return -EIO; 1693 return -EIO;
1691 } 1694 }
@@ -1864,8 +1867,9 @@ static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root,
1864 1867
1865 eb = read_tree_block(root, btrfs_node_blockptr(parent, slot), 1868 eb = read_tree_block(root, btrfs_node_blockptr(parent, slot),
1866 btrfs_node_ptr_generation(parent, slot)); 1869 btrfs_node_ptr_generation(parent, slot));
1867 if (eb && !extent_buffer_uptodate(eb)) { 1870 if (IS_ERR(eb) || !extent_buffer_uptodate(eb)) {
1868 free_extent_buffer(eb); 1871 if (!IS_ERR(eb))
1872 free_extent_buffer(eb);
1869 eb = NULL; 1873 eb = NULL;
1870 } 1874 }
1871 1875
@@ -2494,7 +2498,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
2494 2498
2495 ret = -EAGAIN; 2499 ret = -EAGAIN;
2496 tmp = read_tree_block(root, blocknr, 0); 2500 tmp = read_tree_block(root, blocknr, 0);
2497 if (tmp) { 2501 if (!IS_ERR(tmp)) {
2498 /* 2502 /*
2499 * If the read above didn't mark this buffer up to date, 2503 * If the read above didn't mark this buffer up to date,
2500 * it will never end up being up to date. Set ret to EIO now 2504 * it will never end up being up to date. Set ret to EIO now
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2ef9a4b72d06..7f8377871283 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1149,12 +1149,12 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
1149 1149
1150 buf = btrfs_find_create_tree_block(root, bytenr); 1150 buf = btrfs_find_create_tree_block(root, bytenr);
1151 if (!buf) 1151 if (!buf)
1152 return NULL; 1152 return ERR_PTR(-ENOMEM);
1153 1153
1154 ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); 1154 ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
1155 if (ret) { 1155 if (ret) {
1156 free_extent_buffer(buf); 1156 free_extent_buffer(buf);
1157 return NULL; 1157 return ERR_PTR(ret);
1158 } 1158 }
1159 return buf; 1159 return buf;
1160 1160
@@ -1509,20 +1509,19 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
1509 generation = btrfs_root_generation(&root->root_item); 1509 generation = btrfs_root_generation(&root->root_item);
1510 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 1510 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1511 generation); 1511 generation);
1512 if (!root->node) { 1512 if (IS_ERR(root->node)) {
1513 ret = -ENOMEM; 1513 ret = PTR_ERR(root->node);
1514 goto find_fail; 1514 goto find_fail;
1515 } else if (!btrfs_buffer_uptodate(root->node, generation, 0)) { 1515 } else if (!btrfs_buffer_uptodate(root->node, generation, 0)) {
1516 ret = -EIO; 1516 ret = -EIO;
1517 goto read_fail; 1517 free_extent_buffer(root->node);
1518 goto find_fail;
1518 } 1519 }
1519 root->commit_root = btrfs_root_node(root); 1520 root->commit_root = btrfs_root_node(root);
1520out: 1521out:
1521 btrfs_free_path(path); 1522 btrfs_free_path(path);
1522 return root; 1523 return root;
1523 1524
1524read_fail:
1525 free_extent_buffer(root->node);
1526find_fail: 1525find_fail:
1527 kfree(root); 1526 kfree(root);
1528alloc_fail: 1527alloc_fail:
@@ -2320,8 +2319,11 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
2320 2319
2321 log_tree_root->node = read_tree_block(tree_root, bytenr, 2320 log_tree_root->node = read_tree_block(tree_root, bytenr,
2322 fs_info->generation + 1); 2321 fs_info->generation + 1);
2323 if (!log_tree_root->node || 2322 if (IS_ERR(log_tree_root->node)) {
2324 !extent_buffer_uptodate(log_tree_root->node)) { 2323 printk(KERN_ERR "BTRFS: failed to read log tree\n");
2324 kfree(log_tree_root);
2325 return PTR_ERR(log_tree_root->node);
2326 } else if (!extent_buffer_uptodate(log_tree_root->node)) {
2325 printk(KERN_ERR "BTRFS: failed to read log tree\n"); 2327 printk(KERN_ERR "BTRFS: failed to read log tree\n");
2326 free_extent_buffer(log_tree_root->node); 2328 free_extent_buffer(log_tree_root->node);
2327 kfree(log_tree_root); 2329 kfree(log_tree_root);
@@ -2797,8 +2799,8 @@ int open_ctree(struct super_block *sb,
2797 chunk_root->node = read_tree_block(chunk_root, 2799 chunk_root->node = read_tree_block(chunk_root,
2798 btrfs_super_chunk_root(disk_super), 2800 btrfs_super_chunk_root(disk_super),
2799 generation); 2801 generation);
2800 if (!chunk_root->node || 2802 if (IS_ERR(chunk_root->node) ||
2801 !test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) { 2803 !extent_buffer_uptodate(chunk_root->node)) {
2802 printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n", 2804 printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n",
2803 sb->s_id); 2805 sb->s_id);
2804 goto fail_tree_roots; 2806 goto fail_tree_roots;
@@ -2834,8 +2836,8 @@ retry_root_backup:
2834 tree_root->node = read_tree_block(tree_root, 2836 tree_root->node = read_tree_block(tree_root,
2835 btrfs_super_root(disk_super), 2837 btrfs_super_root(disk_super),
2836 generation); 2838 generation);
2837 if (!tree_root->node || 2839 if (IS_ERR(tree_root->node) ||
2838 !test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) { 2840 !extent_buffer_uptodate(tree_root->node)) {
2839 printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n", 2841 printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n",
2840 sb->s_id); 2842 sb->s_id);
2841 2843
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 076fd7484a82..f1d1216f7feb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -7979,9 +7979,12 @@ walk_down:
7979 child_gen = btrfs_node_ptr_generation(eb, parent_slot); 7979 child_gen = btrfs_node_ptr_generation(eb, parent_slot);
7980 7980
7981 eb = read_tree_block(root, child_bytenr, child_gen); 7981 eb = read_tree_block(root, child_bytenr, child_gen);
7982 if (!eb || !extent_buffer_uptodate(eb)) { 7982 if (IS_ERR(eb)) {
7983 ret = -EIO; 7983 ret = PTR_ERR(eb);
7984 goto out;
7985 } else if (!extent_buffer_uptodate(eb)) {
7984 free_extent_buffer(eb); 7986 free_extent_buffer(eb);
7987 ret = -EIO;
7985 goto out; 7988 goto out;
7986 } 7989 }
7987 7990
@@ -8211,7 +8214,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
8211 if (reada && level == 1) 8214 if (reada && level == 1)
8212 reada_walk_down(trans, root, wc, path); 8215 reada_walk_down(trans, root, wc, path);
8213 next = read_tree_block(root, bytenr, generation); 8216 next = read_tree_block(root, bytenr, generation);
8214 if (!next || !extent_buffer_uptodate(next)) { 8217 if (IS_ERR(next)) {
8218 return PTR_ERR(next);
8219 } else if (!extent_buffer_uptodate(next)) {
8215 free_extent_buffer(next); 8220 free_extent_buffer(next);
8216 return -EIO; 8221 return -EIO;
8217 } 8222 }
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 74b24b01d574..827951fbf7fc 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1847,8 +1847,10 @@ again:
1847 } 1847 }
1848 1848
1849 eb = read_tree_block(dest, old_bytenr, old_ptr_gen); 1849 eb = read_tree_block(dest, old_bytenr, old_ptr_gen);
1850 if (!eb || !extent_buffer_uptodate(eb)) { 1850 if (IS_ERR(eb)) {
1851 ret = (!eb) ? -ENOMEM : -EIO; 1851 ret = PTR_ERR(eb);
1852 } else if (!extent_buffer_uptodate(eb)) {
1853 ret = -EIO;
1852 free_extent_buffer(eb); 1854 free_extent_buffer(eb);
1853 break; 1855 break;
1854 } 1856 }
@@ -2002,7 +2004,9 @@ int walk_down_reloc_tree(struct btrfs_root *root, struct btrfs_path *path,
2002 2004
2003 bytenr = btrfs_node_blockptr(eb, path->slots[i]); 2005 bytenr = btrfs_node_blockptr(eb, path->slots[i]);
2004 eb = read_tree_block(root, bytenr, ptr_gen); 2006 eb = read_tree_block(root, bytenr, ptr_gen);
2005 if (!eb || !extent_buffer_uptodate(eb)) { 2007 if (IS_ERR(eb)) {
2008 return PTR_ERR(eb);
2009 } else if (!extent_buffer_uptodate(eb)) {
2006 free_extent_buffer(eb); 2010 free_extent_buffer(eb);
2007 return -EIO; 2011 return -EIO;
2008 } 2012 }
@@ -2710,7 +2714,10 @@ static int do_relocation(struct btrfs_trans_handle *trans,
2710 blocksize = root->nodesize; 2714 blocksize = root->nodesize;
2711 generation = btrfs_node_ptr_generation(upper->eb, slot); 2715 generation = btrfs_node_ptr_generation(upper->eb, slot);
2712 eb = read_tree_block(root, bytenr, generation); 2716 eb = read_tree_block(root, bytenr, generation);
2713 if (!eb || !extent_buffer_uptodate(eb)) { 2717 if (IS_ERR(eb)) {
2718 err = PTR_ERR(eb);
2719 goto next;
2720 } else if (!extent_buffer_uptodate(eb)) {
2714 free_extent_buffer(eb); 2721 free_extent_buffer(eb);
2715 err = -EIO; 2722 err = -EIO;
2716 goto next; 2723 goto next;
@@ -2873,7 +2880,9 @@ static int get_tree_block_key(struct reloc_control *rc,
2873 BUG_ON(block->key_ready); 2880 BUG_ON(block->key_ready);
2874 eb = read_tree_block(rc->extent_root, block->bytenr, 2881 eb = read_tree_block(rc->extent_root, block->bytenr,
2875 block->key.offset); 2882 block->key.offset);
2876 if (!eb || !extent_buffer_uptodate(eb)) { 2883 if (IS_ERR(eb)) {
2884 return PTR_ERR(eb);
2885 } else if (!extent_buffer_uptodate(eb)) {
2877 free_extent_buffer(eb); 2886 free_extent_buffer(eb);
2878 return -EIO; 2887 return -EIO;
2879 } 2888 }