diff options
author | Josef Bacik <jbacik@fb.com> | 2016-09-23 07:23:28 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-09-26 13:37:06 -0400 |
commit | 4867268c57ff709a7b6b86ae6f6537d846d1443a (patch) | |
tree | e0237d6308ff83ad8dde872e0f3f4eedbe5b6952 | |
parent | 2fd57fcb16483d718043940fd6dfeb176d4dc09c (diff) |
Btrfs: don't BUG() during drop snapshot
Really there's lots of things that can go wrong here, kill all the
BUG_ON()'s and replace the logic ones with ASSERT()'s and return EIO
instead.
Signed-off-by: Josef Bacik <jbacik@fb.com>
[ switched to btrfs_err, errors go to common label ]
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a23597f6d3cd..11802eaaab54 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -8886,15 +8886,13 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
8886 | ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1, | 8886 | ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1, |
8887 | &wc->refs[level - 1], | 8887 | &wc->refs[level - 1], |
8888 | &wc->flags[level - 1]); | 8888 | &wc->flags[level - 1]); |
8889 | if (ret < 0) { | 8889 | if (ret < 0) |
8890 | btrfs_tree_unlock(next); | 8890 | goto out_unlock; |
8891 | free_extent_buffer(next); | ||
8892 | return ret; | ||
8893 | } | ||
8894 | 8891 | ||
8895 | if (unlikely(wc->refs[level - 1] == 0)) { | 8892 | if (unlikely(wc->refs[level - 1] == 0)) { |
8896 | btrfs_err(root->fs_info, "Missing references."); | 8893 | btrfs_err(root->fs_info, "Missing references."); |
8897 | BUG(); | 8894 | ret = -EIO; |
8895 | goto out_unlock; | ||
8898 | } | 8896 | } |
8899 | *lookup_info = 0; | 8897 | *lookup_info = 0; |
8900 | 8898 | ||
@@ -8946,7 +8944,12 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
8946 | } | 8944 | } |
8947 | 8945 | ||
8948 | level--; | 8946 | level--; |
8949 | BUG_ON(level != btrfs_header_level(next)); | 8947 | ASSERT(level == btrfs_header_level(next)); |
8948 | if (level != btrfs_header_level(next)) { | ||
8949 | btrfs_err(root->fs_info, "mismatched level"); | ||
8950 | ret = -EIO; | ||
8951 | goto out_unlock; | ||
8952 | } | ||
8950 | path->nodes[level] = next; | 8953 | path->nodes[level] = next; |
8951 | path->slots[level] = 0; | 8954 | path->slots[level] = 0; |
8952 | path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; | 8955 | path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; |
@@ -8961,8 +8964,15 @@ skip: | |||
8961 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { | 8964 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { |
8962 | parent = path->nodes[level]->start; | 8965 | parent = path->nodes[level]->start; |
8963 | } else { | 8966 | } else { |
8964 | BUG_ON(root->root_key.objectid != | 8967 | ASSERT(root->root_key.objectid == |
8965 | btrfs_header_owner(path->nodes[level])); | 8968 | btrfs_header_owner(path->nodes[level])); |
8969 | if (root->root_key.objectid != | ||
8970 | btrfs_header_owner(path->nodes[level])) { | ||
8971 | btrfs_err(root->fs_info, | ||
8972 | "mismatched block owner"); | ||
8973 | ret = -EIO; | ||
8974 | goto out_unlock; | ||
8975 | } | ||
8966 | parent = 0; | 8976 | parent = 0; |
8967 | } | 8977 | } |
8968 | 8978 | ||
@@ -8977,12 +8987,18 @@ skip: | |||
8977 | } | 8987 | } |
8978 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, | 8988 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, |
8979 | root->root_key.objectid, level - 1, 0); | 8989 | root->root_key.objectid, level - 1, 0); |
8980 | BUG_ON(ret); /* -ENOMEM */ | 8990 | if (ret) |
8991 | goto out_unlock; | ||
8981 | } | 8992 | } |
8993 | |||
8994 | *lookup_info = 1; | ||
8995 | ret = 1; | ||
8996 | |||
8997 | out_unlock: | ||
8982 | btrfs_tree_unlock(next); | 8998 | btrfs_tree_unlock(next); |
8983 | free_extent_buffer(next); | 8999 | free_extent_buffer(next); |
8984 | *lookup_info = 1; | 9000 | |
8985 | return 1; | 9001 | return ret; |
8986 | } | 9002 | } |
8987 | 9003 | ||
8988 | /* | 9004 | /* |