diff options
author | Chris Mason <chris.mason@oracle.com> | 2012-03-28 20:31:37 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-03-28 20:31:37 -0400 |
commit | 1d4284bd6e8d7dd1d5521a6747bdb6dc1caf0225 (patch) | |
tree | a7dde6312ec24eb6368cad7a3efedbf368a5a70c /fs/btrfs/extent-tree.c | |
parent | b5d67f64f9bc656970dacba245410f0faedad18e (diff) | |
parent | 65139ed99234d8505948cdb7a835452eb5c191f9 (diff) |
Merge branch 'error-handling' into for-linus
Conflicts:
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/inode.c
fs/btrfs/scrub.c
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 383 |
1 files changed, 254 insertions, 129 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1b831ac4c079..8b304e3537c4 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -245,7 +245,7 @@ static int exclude_super_stripes(struct btrfs_root *root, | |||
245 | cache->bytes_super += stripe_len; | 245 | cache->bytes_super += stripe_len; |
246 | ret = add_excluded_extent(root, cache->key.objectid, | 246 | ret = add_excluded_extent(root, cache->key.objectid, |
247 | stripe_len); | 247 | stripe_len); |
248 | BUG_ON(ret); | 248 | BUG_ON(ret); /* -ENOMEM */ |
249 | } | 249 | } |
250 | 250 | ||
251 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { | 251 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { |
@@ -253,13 +253,13 @@ static int exclude_super_stripes(struct btrfs_root *root, | |||
253 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, | 253 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, |
254 | cache->key.objectid, bytenr, | 254 | cache->key.objectid, bytenr, |
255 | 0, &logical, &nr, &stripe_len); | 255 | 0, &logical, &nr, &stripe_len); |
256 | BUG_ON(ret); | 256 | BUG_ON(ret); /* -ENOMEM */ |
257 | 257 | ||
258 | while (nr--) { | 258 | while (nr--) { |
259 | cache->bytes_super += stripe_len; | 259 | cache->bytes_super += stripe_len; |
260 | ret = add_excluded_extent(root, logical[nr], | 260 | ret = add_excluded_extent(root, logical[nr], |
261 | stripe_len); | 261 | stripe_len); |
262 | BUG_ON(ret); | 262 | BUG_ON(ret); /* -ENOMEM */ |
263 | } | 263 | } |
264 | 264 | ||
265 | kfree(logical); | 265 | kfree(logical); |
@@ -321,7 +321,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, | |||
321 | total_added += size; | 321 | total_added += size; |
322 | ret = btrfs_add_free_space(block_group, start, | 322 | ret = btrfs_add_free_space(block_group, start, |
323 | size); | 323 | size); |
324 | BUG_ON(ret); | 324 | BUG_ON(ret); /* -ENOMEM or logic error */ |
325 | start = extent_end + 1; | 325 | start = extent_end + 1; |
326 | } else { | 326 | } else { |
327 | break; | 327 | break; |
@@ -332,7 +332,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, | |||
332 | size = end - start; | 332 | size = end - start; |
333 | total_added += size; | 333 | total_added += size; |
334 | ret = btrfs_add_free_space(block_group, start, size); | 334 | ret = btrfs_add_free_space(block_group, start, size); |
335 | BUG_ON(ret); | 335 | BUG_ON(ret); /* -ENOMEM or logic error */ |
336 | } | 336 | } |
337 | 337 | ||
338 | return total_added; | 338 | return total_added; |
@@ -474,7 +474,8 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
474 | int ret = 0; | 474 | int ret = 0; |
475 | 475 | ||
476 | caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); | 476 | caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); |
477 | BUG_ON(!caching_ctl); | 477 | if (!caching_ctl) |
478 | return -ENOMEM; | ||
478 | 479 | ||
479 | INIT_LIST_HEAD(&caching_ctl->list); | 480 | INIT_LIST_HEAD(&caching_ctl->list); |
480 | mutex_init(&caching_ctl->mutex); | 481 | mutex_init(&caching_ctl->mutex); |
@@ -982,7 +983,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, | |||
982 | ret = btrfs_next_leaf(root, path); | 983 | ret = btrfs_next_leaf(root, path); |
983 | if (ret < 0) | 984 | if (ret < 0) |
984 | return ret; | 985 | return ret; |
985 | BUG_ON(ret > 0); | 986 | BUG_ON(ret > 0); /* Corruption */ |
986 | leaf = path->nodes[0]; | 987 | leaf = path->nodes[0]; |
987 | } | 988 | } |
988 | btrfs_item_key_to_cpu(leaf, &found_key, | 989 | btrfs_item_key_to_cpu(leaf, &found_key, |
@@ -1008,9 +1009,9 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, | |||
1008 | new_size + extra_size, 1); | 1009 | new_size + extra_size, 1); |
1009 | if (ret < 0) | 1010 | if (ret < 0) |
1010 | return ret; | 1011 | return ret; |
1011 | BUG_ON(ret); | 1012 | BUG_ON(ret); /* Corruption */ |
1012 | 1013 | ||
1013 | ret = btrfs_extend_item(trans, root, path, new_size); | 1014 | btrfs_extend_item(trans, root, path, new_size); |
1014 | 1015 | ||
1015 | leaf = path->nodes[0]; | 1016 | leaf = path->nodes[0]; |
1016 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 1017 | item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
@@ -1478,7 +1479,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1478 | err = ret; | 1479 | err = ret; |
1479 | goto out; | 1480 | goto out; |
1480 | } | 1481 | } |
1481 | BUG_ON(ret); | 1482 | if (ret && !insert) { |
1483 | err = -ENOENT; | ||
1484 | goto out; | ||
1485 | } | ||
1486 | BUG_ON(ret); /* Corruption */ | ||
1482 | 1487 | ||
1483 | leaf = path->nodes[0]; | 1488 | leaf = path->nodes[0]; |
1484 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 1489 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
@@ -1592,13 +1597,13 @@ out: | |||
1592 | * helper to add new inline back ref | 1597 | * helper to add new inline back ref |
1593 | */ | 1598 | */ |
1594 | static noinline_for_stack | 1599 | static noinline_for_stack |
1595 | int setup_inline_extent_backref(struct btrfs_trans_handle *trans, | 1600 | void setup_inline_extent_backref(struct btrfs_trans_handle *trans, |
1596 | struct btrfs_root *root, | 1601 | struct btrfs_root *root, |
1597 | struct btrfs_path *path, | 1602 | struct btrfs_path *path, |
1598 | struct btrfs_extent_inline_ref *iref, | 1603 | struct btrfs_extent_inline_ref *iref, |
1599 | u64 parent, u64 root_objectid, | 1604 | u64 parent, u64 root_objectid, |
1600 | u64 owner, u64 offset, int refs_to_add, | 1605 | u64 owner, u64 offset, int refs_to_add, |
1601 | struct btrfs_delayed_extent_op *extent_op) | 1606 | struct btrfs_delayed_extent_op *extent_op) |
1602 | { | 1607 | { |
1603 | struct extent_buffer *leaf; | 1608 | struct extent_buffer *leaf; |
1604 | struct btrfs_extent_item *ei; | 1609 | struct btrfs_extent_item *ei; |
@@ -1608,7 +1613,6 @@ int setup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1608 | u64 refs; | 1613 | u64 refs; |
1609 | int size; | 1614 | int size; |
1610 | int type; | 1615 | int type; |
1611 | int ret; | ||
1612 | 1616 | ||
1613 | leaf = path->nodes[0]; | 1617 | leaf = path->nodes[0]; |
1614 | ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 1618 | ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
@@ -1617,7 +1621,7 @@ int setup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1617 | type = extent_ref_type(parent, owner); | 1621 | type = extent_ref_type(parent, owner); |
1618 | size = btrfs_extent_inline_ref_size(type); | 1622 | size = btrfs_extent_inline_ref_size(type); |
1619 | 1623 | ||
1620 | ret = btrfs_extend_item(trans, root, path, size); | 1624 | btrfs_extend_item(trans, root, path, size); |
1621 | 1625 | ||
1622 | ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); | 1626 | ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); |
1623 | refs = btrfs_extent_refs(leaf, ei); | 1627 | refs = btrfs_extent_refs(leaf, ei); |
@@ -1652,7 +1656,6 @@ int setup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1652 | btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid); | 1656 | btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid); |
1653 | } | 1657 | } |
1654 | btrfs_mark_buffer_dirty(leaf); | 1658 | btrfs_mark_buffer_dirty(leaf); |
1655 | return 0; | ||
1656 | } | 1659 | } |
1657 | 1660 | ||
1658 | static int lookup_extent_backref(struct btrfs_trans_handle *trans, | 1661 | static int lookup_extent_backref(struct btrfs_trans_handle *trans, |
@@ -1687,12 +1690,12 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans, | |||
1687 | * helper to update/remove inline back ref | 1690 | * helper to update/remove inline back ref |
1688 | */ | 1691 | */ |
1689 | static noinline_for_stack | 1692 | static noinline_for_stack |
1690 | int update_inline_extent_backref(struct btrfs_trans_handle *trans, | 1693 | void update_inline_extent_backref(struct btrfs_trans_handle *trans, |
1691 | struct btrfs_root *root, | 1694 | struct btrfs_root *root, |
1692 | struct btrfs_path *path, | 1695 | struct btrfs_path *path, |
1693 | struct btrfs_extent_inline_ref *iref, | 1696 | struct btrfs_extent_inline_ref *iref, |
1694 | int refs_to_mod, | 1697 | int refs_to_mod, |
1695 | struct btrfs_delayed_extent_op *extent_op) | 1698 | struct btrfs_delayed_extent_op *extent_op) |
1696 | { | 1699 | { |
1697 | struct extent_buffer *leaf; | 1700 | struct extent_buffer *leaf; |
1698 | struct btrfs_extent_item *ei; | 1701 | struct btrfs_extent_item *ei; |
@@ -1703,7 +1706,6 @@ int update_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1703 | u32 item_size; | 1706 | u32 item_size; |
1704 | int size; | 1707 | int size; |
1705 | int type; | 1708 | int type; |
1706 | int ret; | ||
1707 | u64 refs; | 1709 | u64 refs; |
1708 | 1710 | ||
1709 | leaf = path->nodes[0]; | 1711 | leaf = path->nodes[0]; |
@@ -1745,10 +1747,9 @@ int update_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1745 | memmove_extent_buffer(leaf, ptr, ptr + size, | 1747 | memmove_extent_buffer(leaf, ptr, ptr + size, |
1746 | end - ptr - size); | 1748 | end - ptr - size); |
1747 | item_size -= size; | 1749 | item_size -= size; |
1748 | ret = btrfs_truncate_item(trans, root, path, item_size, 1); | 1750 | btrfs_truncate_item(trans, root, path, item_size, 1); |
1749 | } | 1751 | } |
1750 | btrfs_mark_buffer_dirty(leaf); | 1752 | btrfs_mark_buffer_dirty(leaf); |
1751 | return 0; | ||
1752 | } | 1753 | } |
1753 | 1754 | ||
1754 | static noinline_for_stack | 1755 | static noinline_for_stack |
@@ -1768,13 +1769,13 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1768 | root_objectid, owner, offset, 1); | 1769 | root_objectid, owner, offset, 1); |
1769 | if (ret == 0) { | 1770 | if (ret == 0) { |
1770 | BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID); | 1771 | BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID); |
1771 | ret = update_inline_extent_backref(trans, root, path, iref, | 1772 | update_inline_extent_backref(trans, root, path, iref, |
1772 | refs_to_add, extent_op); | 1773 | refs_to_add, extent_op); |
1773 | } else if (ret == -ENOENT) { | 1774 | } else if (ret == -ENOENT) { |
1774 | ret = setup_inline_extent_backref(trans, root, path, iref, | 1775 | setup_inline_extent_backref(trans, root, path, iref, parent, |
1775 | parent, root_objectid, | 1776 | root_objectid, owner, offset, |
1776 | owner, offset, refs_to_add, | 1777 | refs_to_add, extent_op); |
1777 | extent_op); | 1778 | ret = 0; |
1778 | } | 1779 | } |
1779 | return ret; | 1780 | return ret; |
1780 | } | 1781 | } |
@@ -1804,12 +1805,12 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, | |||
1804 | struct btrfs_extent_inline_ref *iref, | 1805 | struct btrfs_extent_inline_ref *iref, |
1805 | int refs_to_drop, int is_data) | 1806 | int refs_to_drop, int is_data) |
1806 | { | 1807 | { |
1807 | int ret; | 1808 | int ret = 0; |
1808 | 1809 | ||
1809 | BUG_ON(!is_data && refs_to_drop != 1); | 1810 | BUG_ON(!is_data && refs_to_drop != 1); |
1810 | if (iref) { | 1811 | if (iref) { |
1811 | ret = update_inline_extent_backref(trans, root, path, iref, | 1812 | update_inline_extent_backref(trans, root, path, iref, |
1812 | -refs_to_drop, NULL); | 1813 | -refs_to_drop, NULL); |
1813 | } else if (is_data) { | 1814 | } else if (is_data) { |
1814 | ret = remove_extent_data_ref(trans, root, path, refs_to_drop); | 1815 | ret = remove_extent_data_ref(trans, root, path, refs_to_drop); |
1815 | } else { | 1816 | } else { |
@@ -1835,6 +1836,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1835 | /* Tell the block device(s) that the sectors can be discarded */ | 1836 | /* Tell the block device(s) that the sectors can be discarded */ |
1836 | ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD, | 1837 | ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD, |
1837 | bytenr, &num_bytes, &bbio, 0); | 1838 | bytenr, &num_bytes, &bbio, 0); |
1839 | /* Error condition is -ENOMEM */ | ||
1838 | if (!ret) { | 1840 | if (!ret) { |
1839 | struct btrfs_bio_stripe *stripe = bbio->stripes; | 1841 | struct btrfs_bio_stripe *stripe = bbio->stripes; |
1840 | int i; | 1842 | int i; |
@@ -1850,7 +1852,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1850 | if (!ret) | 1852 | if (!ret) |
1851 | discarded_bytes += stripe->length; | 1853 | discarded_bytes += stripe->length; |
1852 | else if (ret != -EOPNOTSUPP) | 1854 | else if (ret != -EOPNOTSUPP) |
1853 | break; | 1855 | break; /* Logic errors or -ENOMEM, or -EIO but I don't know how that could happen JDM */ |
1854 | 1856 | ||
1855 | /* | 1857 | /* |
1856 | * Just in case we get back EOPNOTSUPP for some reason, | 1858 | * Just in case we get back EOPNOTSUPP for some reason, |
@@ -1869,6 +1871,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1869 | return ret; | 1871 | return ret; |
1870 | } | 1872 | } |
1871 | 1873 | ||
1874 | /* Can return -ENOMEM */ | ||
1872 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 1875 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
1873 | struct btrfs_root *root, | 1876 | struct btrfs_root *root, |
1874 | u64 bytenr, u64 num_bytes, u64 parent, | 1877 | u64 bytenr, u64 num_bytes, u64 parent, |
@@ -1944,7 +1947,8 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
1944 | ret = insert_extent_backref(trans, root->fs_info->extent_root, | 1947 | ret = insert_extent_backref(trans, root->fs_info->extent_root, |
1945 | path, bytenr, parent, root_objectid, | 1948 | path, bytenr, parent, root_objectid, |
1946 | owner, offset, refs_to_add); | 1949 | owner, offset, refs_to_add); |
1947 | BUG_ON(ret); | 1950 | if (ret) |
1951 | btrfs_abort_transaction(trans, root, ret); | ||
1948 | out: | 1952 | out: |
1949 | btrfs_free_path(path); | 1953 | btrfs_free_path(path); |
1950 | return err; | 1954 | return err; |
@@ -2031,6 +2035,9 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, | |||
2031 | int ret; | 2035 | int ret; |
2032 | int err = 0; | 2036 | int err = 0; |
2033 | 2037 | ||
2038 | if (trans->aborted) | ||
2039 | return 0; | ||
2040 | |||
2034 | path = btrfs_alloc_path(); | 2041 | path = btrfs_alloc_path(); |
2035 | if (!path) | 2042 | if (!path) |
2036 | return -ENOMEM; | 2043 | return -ENOMEM; |
@@ -2128,7 +2135,11 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, | |||
2128 | struct btrfs_delayed_extent_op *extent_op, | 2135 | struct btrfs_delayed_extent_op *extent_op, |
2129 | int insert_reserved) | 2136 | int insert_reserved) |
2130 | { | 2137 | { |
2131 | int ret; | 2138 | int ret = 0; |
2139 | |||
2140 | if (trans->aborted) | ||
2141 | return 0; | ||
2142 | |||
2132 | if (btrfs_delayed_ref_is_head(node)) { | 2143 | if (btrfs_delayed_ref_is_head(node)) { |
2133 | struct btrfs_delayed_ref_head *head; | 2144 | struct btrfs_delayed_ref_head *head; |
2134 | /* | 2145 | /* |
@@ -2146,11 +2157,10 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, | |||
2146 | ret = btrfs_del_csums(trans, root, | 2157 | ret = btrfs_del_csums(trans, root, |
2147 | node->bytenr, | 2158 | node->bytenr, |
2148 | node->num_bytes); | 2159 | node->num_bytes); |
2149 | BUG_ON(ret); | ||
2150 | } | 2160 | } |
2151 | } | 2161 | } |
2152 | mutex_unlock(&head->mutex); | 2162 | mutex_unlock(&head->mutex); |
2153 | return 0; | 2163 | return ret; |
2154 | } | 2164 | } |
2155 | 2165 | ||
2156 | if (node->type == BTRFS_TREE_BLOCK_REF_KEY || | 2166 | if (node->type == BTRFS_TREE_BLOCK_REF_KEY || |
@@ -2197,6 +2207,10 @@ again: | |||
2197 | return NULL; | 2207 | return NULL; |
2198 | } | 2208 | } |
2199 | 2209 | ||
2210 | /* | ||
2211 | * Returns 0 on success or if called with an already aborted transaction. | ||
2212 | * Returns -ENOMEM or -EIO on failure and will abort the transaction. | ||
2213 | */ | ||
2200 | static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | 2214 | static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, |
2201 | struct btrfs_root *root, | 2215 | struct btrfs_root *root, |
2202 | struct list_head *cluster) | 2216 | struct list_head *cluster) |
@@ -2285,9 +2299,13 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
2285 | 2299 | ||
2286 | ret = run_delayed_extent_op(trans, root, | 2300 | ret = run_delayed_extent_op(trans, root, |
2287 | ref, extent_op); | 2301 | ref, extent_op); |
2288 | BUG_ON(ret); | ||
2289 | kfree(extent_op); | 2302 | kfree(extent_op); |
2290 | 2303 | ||
2304 | if (ret) { | ||
2305 | printk(KERN_DEBUG "btrfs: run_delayed_extent_op returned %d\n", ret); | ||
2306 | return ret; | ||
2307 | } | ||
2308 | |||
2291 | goto next; | 2309 | goto next; |
2292 | } | 2310 | } |
2293 | 2311 | ||
@@ -2308,11 +2326,16 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
2308 | 2326 | ||
2309 | ret = run_one_delayed_ref(trans, root, ref, extent_op, | 2327 | ret = run_one_delayed_ref(trans, root, ref, extent_op, |
2310 | must_insert_reserved); | 2328 | must_insert_reserved); |
2311 | BUG_ON(ret); | ||
2312 | 2329 | ||
2313 | btrfs_put_delayed_ref(ref); | 2330 | btrfs_put_delayed_ref(ref); |
2314 | kfree(extent_op); | 2331 | kfree(extent_op); |
2315 | count++; | 2332 | count++; |
2333 | |||
2334 | if (ret) { | ||
2335 | printk(KERN_DEBUG "btrfs: run_one_delayed_ref returned %d\n", ret); | ||
2336 | return ret; | ||
2337 | } | ||
2338 | |||
2316 | next: | 2339 | next: |
2317 | do_chunk_alloc(trans, root->fs_info->extent_root, | 2340 | do_chunk_alloc(trans, root->fs_info->extent_root, |
2318 | 2 * 1024 * 1024, | 2341 | 2 * 1024 * 1024, |
@@ -2347,6 +2370,9 @@ static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs, | |||
2347 | * 0, which means to process everything in the tree at the start | 2370 | * 0, which means to process everything in the tree at the start |
2348 | * of the run (but not newly added entries), or it can be some target | 2371 | * of the run (but not newly added entries), or it can be some target |
2349 | * number you'd like to process. | 2372 | * number you'd like to process. |
2373 | * | ||
2374 | * Returns 0 on success or if called with an aborted transaction | ||
2375 | * Returns <0 on error and aborts the transaction | ||
2350 | */ | 2376 | */ |
2351 | int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | 2377 | int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, |
2352 | struct btrfs_root *root, unsigned long count) | 2378 | struct btrfs_root *root, unsigned long count) |
@@ -2362,6 +2388,10 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2362 | unsigned long num_refs = 0; | 2388 | unsigned long num_refs = 0; |
2363 | int consider_waiting; | 2389 | int consider_waiting; |
2364 | 2390 | ||
2391 | /* We'll clean this up in btrfs_cleanup_transaction */ | ||
2392 | if (trans->aborted) | ||
2393 | return 0; | ||
2394 | |||
2365 | if (root == root->fs_info->extent_root) | 2395 | if (root == root->fs_info->extent_root) |
2366 | root = root->fs_info->tree_root; | 2396 | root = root->fs_info->tree_root; |
2367 | 2397 | ||
@@ -2419,7 +2449,11 @@ again: | |||
2419 | } | 2449 | } |
2420 | 2450 | ||
2421 | ret = run_clustered_refs(trans, root, &cluster); | 2451 | ret = run_clustered_refs(trans, root, &cluster); |
2422 | BUG_ON(ret < 0); | 2452 | if (ret < 0) { |
2453 | spin_unlock(&delayed_refs->lock); | ||
2454 | btrfs_abort_transaction(trans, root, ret); | ||
2455 | return ret; | ||
2456 | } | ||
2423 | 2457 | ||
2424 | count -= min_t(unsigned long, ret, count); | 2458 | count -= min_t(unsigned long, ret, count); |
2425 | 2459 | ||
@@ -2584,7 +2618,7 @@ static noinline int check_committed_ref(struct btrfs_trans_handle *trans, | |||
2584 | ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); | 2618 | ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); |
2585 | if (ret < 0) | 2619 | if (ret < 0) |
2586 | goto out; | 2620 | goto out; |
2587 | BUG_ON(ret == 0); | 2621 | BUG_ON(ret == 0); /* Corruption */ |
2588 | 2622 | ||
2589 | ret = -ENOENT; | 2623 | ret = -ENOENT; |
2590 | if (path->slots[0] == 0) | 2624 | if (path->slots[0] == 0) |
@@ -2738,7 +2772,6 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
2738 | } | 2772 | } |
2739 | return 0; | 2773 | return 0; |
2740 | fail: | 2774 | fail: |
2741 | BUG(); | ||
2742 | return ret; | 2775 | return ret; |
2743 | } | 2776 | } |
2744 | 2777 | ||
@@ -2767,7 +2800,7 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
2767 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); | 2800 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); |
2768 | if (ret < 0) | 2801 | if (ret < 0) |
2769 | goto fail; | 2802 | goto fail; |
2770 | BUG_ON(ret); | 2803 | BUG_ON(ret); /* Corruption */ |
2771 | 2804 | ||
2772 | leaf = path->nodes[0]; | 2805 | leaf = path->nodes[0]; |
2773 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); | 2806 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); |
@@ -2775,8 +2808,10 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
2775 | btrfs_mark_buffer_dirty(leaf); | 2808 | btrfs_mark_buffer_dirty(leaf); |
2776 | btrfs_release_path(path); | 2809 | btrfs_release_path(path); |
2777 | fail: | 2810 | fail: |
2778 | if (ret) | 2811 | if (ret) { |
2812 | btrfs_abort_transaction(trans, root, ret); | ||
2779 | return ret; | 2813 | return ret; |
2814 | } | ||
2780 | return 0; | 2815 | return 0; |
2781 | 2816 | ||
2782 | } | 2817 | } |
@@ -2949,7 +2984,8 @@ again: | |||
2949 | if (last == 0) { | 2984 | if (last == 0) { |
2950 | err = btrfs_run_delayed_refs(trans, root, | 2985 | err = btrfs_run_delayed_refs(trans, root, |
2951 | (unsigned long)-1); | 2986 | (unsigned long)-1); |
2952 | BUG_ON(err); | 2987 | if (err) /* File system offline */ |
2988 | goto out; | ||
2953 | } | 2989 | } |
2954 | 2990 | ||
2955 | cache = btrfs_lookup_first_block_group(root->fs_info, last); | 2991 | cache = btrfs_lookup_first_block_group(root->fs_info, last); |
@@ -2976,7 +3012,9 @@ again: | |||
2976 | last = cache->key.objectid + cache->key.offset; | 3012 | last = cache->key.objectid + cache->key.offset; |
2977 | 3013 | ||
2978 | err = write_one_cache_group(trans, root, path, cache); | 3014 | err = write_one_cache_group(trans, root, path, cache); |
2979 | BUG_ON(err); | 3015 | if (err) /* File system offline */ |
3016 | goto out; | ||
3017 | |||
2980 | btrfs_put_block_group(cache); | 3018 | btrfs_put_block_group(cache); |
2981 | } | 3019 | } |
2982 | 3020 | ||
@@ -2989,7 +3027,8 @@ again: | |||
2989 | if (last == 0) { | 3027 | if (last == 0) { |
2990 | err = btrfs_run_delayed_refs(trans, root, | 3028 | err = btrfs_run_delayed_refs(trans, root, |
2991 | (unsigned long)-1); | 3029 | (unsigned long)-1); |
2992 | BUG_ON(err); | 3030 | if (err) /* File system offline */ |
3031 | goto out; | ||
2993 | } | 3032 | } |
2994 | 3033 | ||
2995 | cache = btrfs_lookup_first_block_group(root->fs_info, last); | 3034 | cache = btrfs_lookup_first_block_group(root->fs_info, last); |
@@ -3014,20 +3053,21 @@ again: | |||
3014 | continue; | 3053 | continue; |
3015 | } | 3054 | } |
3016 | 3055 | ||
3017 | btrfs_write_out_cache(root, trans, cache, path); | 3056 | err = btrfs_write_out_cache(root, trans, cache, path); |
3018 | 3057 | ||
3019 | /* | 3058 | /* |
3020 | * If we didn't have an error then the cache state is still | 3059 | * If we didn't have an error then the cache state is still |
3021 | * NEED_WRITE, so we can set it to WRITTEN. | 3060 | * NEED_WRITE, so we can set it to WRITTEN. |
3022 | */ | 3061 | */ |
3023 | if (cache->disk_cache_state == BTRFS_DC_NEED_WRITE) | 3062 | if (!err && cache->disk_cache_state == BTRFS_DC_NEED_WRITE) |
3024 | cache->disk_cache_state = BTRFS_DC_WRITTEN; | 3063 | cache->disk_cache_state = BTRFS_DC_WRITTEN; |
3025 | last = cache->key.objectid + cache->key.offset; | 3064 | last = cache->key.objectid + cache->key.offset; |
3026 | btrfs_put_block_group(cache); | 3065 | btrfs_put_block_group(cache); |
3027 | } | 3066 | } |
3067 | out: | ||
3028 | 3068 | ||
3029 | btrfs_free_path(path); | 3069 | btrfs_free_path(path); |
3030 | return 0; | 3070 | return err; |
3031 | } | 3071 | } |
3032 | 3072 | ||
3033 | int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr) | 3073 | int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr) |
@@ -3411,9 +3451,9 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
3411 | if (!space_info) { | 3451 | if (!space_info) { |
3412 | ret = update_space_info(extent_root->fs_info, flags, | 3452 | ret = update_space_info(extent_root->fs_info, flags, |
3413 | 0, 0, &space_info); | 3453 | 0, 0, &space_info); |
3414 | BUG_ON(ret); | 3454 | BUG_ON(ret); /* -ENOMEM */ |
3415 | } | 3455 | } |
3416 | BUG_ON(!space_info); | 3456 | BUG_ON(!space_info); /* Logic error */ |
3417 | 3457 | ||
3418 | again: | 3458 | again: |
3419 | spin_lock(&space_info->lock); | 3459 | spin_lock(&space_info->lock); |
@@ -3678,8 +3718,10 @@ again: | |||
3678 | ret = wait_event_interruptible(space_info->wait, | 3718 | ret = wait_event_interruptible(space_info->wait, |
3679 | !space_info->flush); | 3719 | !space_info->flush); |
3680 | /* Must have been interrupted, return */ | 3720 | /* Must have been interrupted, return */ |
3681 | if (ret) | 3721 | if (ret) { |
3722 | printk(KERN_DEBUG "btrfs: %s returning -EINTR\n", __func__); | ||
3682 | return -EINTR; | 3723 | return -EINTR; |
3724 | } | ||
3683 | 3725 | ||
3684 | spin_lock(&space_info->lock); | 3726 | spin_lock(&space_info->lock); |
3685 | } | 3727 | } |
@@ -3836,8 +3878,9 @@ out: | |||
3836 | return ret; | 3878 | return ret; |
3837 | } | 3879 | } |
3838 | 3880 | ||
3839 | static struct btrfs_block_rsv *get_block_rsv(struct btrfs_trans_handle *trans, | 3881 | static struct btrfs_block_rsv *get_block_rsv( |
3840 | struct btrfs_root *root) | 3882 | const struct btrfs_trans_handle *trans, |
3883 | const struct btrfs_root *root) | ||
3841 | { | 3884 | { |
3842 | struct btrfs_block_rsv *block_rsv = NULL; | 3885 | struct btrfs_block_rsv *block_rsv = NULL; |
3843 | 3886 | ||
@@ -4204,6 +4247,7 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, | |||
4204 | trans->bytes_reserved = 0; | 4247 | trans->bytes_reserved = 0; |
4205 | } | 4248 | } |
4206 | 4249 | ||
4250 | /* Can only return 0 or -ENOSPC */ | ||
4207 | int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, | 4251 | int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, |
4208 | struct inode *inode) | 4252 | struct inode *inode) |
4209 | { | 4253 | { |
@@ -4540,7 +4584,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
4540 | while (total) { | 4584 | while (total) { |
4541 | cache = btrfs_lookup_block_group(info, bytenr); | 4585 | cache = btrfs_lookup_block_group(info, bytenr); |
4542 | if (!cache) | 4586 | if (!cache) |
4543 | return -1; | 4587 | return -ENOENT; |
4544 | if (cache->flags & (BTRFS_BLOCK_GROUP_DUP | | 4588 | if (cache->flags & (BTRFS_BLOCK_GROUP_DUP | |
4545 | BTRFS_BLOCK_GROUP_RAID1 | | 4589 | BTRFS_BLOCK_GROUP_RAID1 | |
4546 | BTRFS_BLOCK_GROUP_RAID10)) | 4590 | BTRFS_BLOCK_GROUP_RAID10)) |
@@ -4643,7 +4687,7 @@ int btrfs_pin_extent(struct btrfs_root *root, | |||
4643 | struct btrfs_block_group_cache *cache; | 4687 | struct btrfs_block_group_cache *cache; |
4644 | 4688 | ||
4645 | cache = btrfs_lookup_block_group(root->fs_info, bytenr); | 4689 | cache = btrfs_lookup_block_group(root->fs_info, bytenr); |
4646 | BUG_ON(!cache); | 4690 | BUG_ON(!cache); /* Logic error */ |
4647 | 4691 | ||
4648 | pin_down_extent(root, cache, bytenr, num_bytes, reserved); | 4692 | pin_down_extent(root, cache, bytenr, num_bytes, reserved); |
4649 | 4693 | ||
@@ -4661,7 +4705,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans, | |||
4661 | struct btrfs_block_group_cache *cache; | 4705 | struct btrfs_block_group_cache *cache; |
4662 | 4706 | ||
4663 | cache = btrfs_lookup_block_group(root->fs_info, bytenr); | 4707 | cache = btrfs_lookup_block_group(root->fs_info, bytenr); |
4664 | BUG_ON(!cache); | 4708 | BUG_ON(!cache); /* Logic error */ |
4665 | 4709 | ||
4666 | /* | 4710 | /* |
4667 | * pull in the free space cache (if any) so that our pin | 4711 | * pull in the free space cache (if any) so that our pin |
@@ -4706,6 +4750,7 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | |||
4706 | { | 4750 | { |
4707 | struct btrfs_space_info *space_info = cache->space_info; | 4751 | struct btrfs_space_info *space_info = cache->space_info; |
4708 | int ret = 0; | 4752 | int ret = 0; |
4753 | |||
4709 | spin_lock(&space_info->lock); | 4754 | spin_lock(&space_info->lock); |
4710 | spin_lock(&cache->lock); | 4755 | spin_lock(&cache->lock); |
4711 | if (reserve != RESERVE_FREE) { | 4756 | if (reserve != RESERVE_FREE) { |
@@ -4734,7 +4779,7 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | |||
4734 | return ret; | 4779 | return ret; |
4735 | } | 4780 | } |
4736 | 4781 | ||
4737 | int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | 4782 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, |
4738 | struct btrfs_root *root) | 4783 | struct btrfs_root *root) |
4739 | { | 4784 | { |
4740 | struct btrfs_fs_info *fs_info = root->fs_info; | 4785 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -4764,7 +4809,6 @@ int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
4764 | up_write(&fs_info->extent_commit_sem); | 4809 | up_write(&fs_info->extent_commit_sem); |
4765 | 4810 | ||
4766 | update_global_block_rsv(fs_info); | 4811 | update_global_block_rsv(fs_info); |
4767 | return 0; | ||
4768 | } | 4812 | } |
4769 | 4813 | ||
4770 | static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) | 4814 | static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) |
@@ -4779,7 +4823,7 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) | |||
4779 | if (cache) | 4823 | if (cache) |
4780 | btrfs_put_block_group(cache); | 4824 | btrfs_put_block_group(cache); |
4781 | cache = btrfs_lookup_block_group(fs_info, start); | 4825 | cache = btrfs_lookup_block_group(fs_info, start); |
4782 | BUG_ON(!cache); | 4826 | BUG_ON(!cache); /* Logic error */ |
4783 | } | 4827 | } |
4784 | 4828 | ||
4785 | len = cache->key.objectid + cache->key.offset - start; | 4829 | len = cache->key.objectid + cache->key.offset - start; |
@@ -4816,6 +4860,9 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
4816 | u64 end; | 4860 | u64 end; |
4817 | int ret; | 4861 | int ret; |
4818 | 4862 | ||
4863 | if (trans->aborted) | ||
4864 | return 0; | ||
4865 | |||
4819 | if (fs_info->pinned_extents == &fs_info->freed_extents[0]) | 4866 | if (fs_info->pinned_extents == &fs_info->freed_extents[0]) |
4820 | unpin = &fs_info->freed_extents[1]; | 4867 | unpin = &fs_info->freed_extents[1]; |
4821 | else | 4868 | else |
@@ -4901,7 +4948,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
4901 | ret = remove_extent_backref(trans, extent_root, path, | 4948 | ret = remove_extent_backref(trans, extent_root, path, |
4902 | NULL, refs_to_drop, | 4949 | NULL, refs_to_drop, |
4903 | is_data); | 4950 | is_data); |
4904 | BUG_ON(ret); | 4951 | if (ret) |
4952 | goto abort; | ||
4905 | btrfs_release_path(path); | 4953 | btrfs_release_path(path); |
4906 | path->leave_spinning = 1; | 4954 | path->leave_spinning = 1; |
4907 | 4955 | ||
@@ -4919,10 +4967,11 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
4919 | btrfs_print_leaf(extent_root, | 4967 | btrfs_print_leaf(extent_root, |
4920 | path->nodes[0]); | 4968 | path->nodes[0]); |
4921 | } | 4969 | } |
4922 | BUG_ON(ret); | 4970 | if (ret < 0) |
4971 | goto abort; | ||
4923 | extent_slot = path->slots[0]; | 4972 | extent_slot = path->slots[0]; |
4924 | } | 4973 | } |
4925 | } else { | 4974 | } else if (ret == -ENOENT) { |
4926 | btrfs_print_leaf(extent_root, path->nodes[0]); | 4975 | btrfs_print_leaf(extent_root, path->nodes[0]); |
4927 | WARN_ON(1); | 4976 | WARN_ON(1); |
4928 | printk(KERN_ERR "btrfs unable to find ref byte nr %llu " | 4977 | printk(KERN_ERR "btrfs unable to find ref byte nr %llu " |
@@ -4932,6 +4981,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
4932 | (unsigned long long)root_objectid, | 4981 | (unsigned long long)root_objectid, |
4933 | (unsigned long long)owner_objectid, | 4982 | (unsigned long long)owner_objectid, |
4934 | (unsigned long long)owner_offset); | 4983 | (unsigned long long)owner_offset); |
4984 | } else { | ||
4985 | goto abort; | ||
4935 | } | 4986 | } |
4936 | 4987 | ||
4937 | leaf = path->nodes[0]; | 4988 | leaf = path->nodes[0]; |
@@ -4941,7 +4992,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
4941 | BUG_ON(found_extent || extent_slot != path->slots[0]); | 4992 | BUG_ON(found_extent || extent_slot != path->slots[0]); |
4942 | ret = convert_extent_item_v0(trans, extent_root, path, | 4993 | ret = convert_extent_item_v0(trans, extent_root, path, |
4943 | owner_objectid, 0); | 4994 | owner_objectid, 0); |
4944 | BUG_ON(ret < 0); | 4995 | if (ret < 0) |
4996 | goto abort; | ||
4945 | 4997 | ||
4946 | btrfs_release_path(path); | 4998 | btrfs_release_path(path); |
4947 | path->leave_spinning = 1; | 4999 | path->leave_spinning = 1; |
@@ -4958,7 +5010,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
4958 | (unsigned long long)bytenr); | 5010 | (unsigned long long)bytenr); |
4959 | btrfs_print_leaf(extent_root, path->nodes[0]); | 5011 | btrfs_print_leaf(extent_root, path->nodes[0]); |
4960 | } | 5012 | } |
4961 | BUG_ON(ret); | 5013 | if (ret < 0) |
5014 | goto abort; | ||
4962 | extent_slot = path->slots[0]; | 5015 | extent_slot = path->slots[0]; |
4963 | leaf = path->nodes[0]; | 5016 | leaf = path->nodes[0]; |
4964 | item_size = btrfs_item_size_nr(leaf, extent_slot); | 5017 | item_size = btrfs_item_size_nr(leaf, extent_slot); |
@@ -4995,7 +5048,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
4995 | ret = remove_extent_backref(trans, extent_root, path, | 5048 | ret = remove_extent_backref(trans, extent_root, path, |
4996 | iref, refs_to_drop, | 5049 | iref, refs_to_drop, |
4997 | is_data); | 5050 | is_data); |
4998 | BUG_ON(ret); | 5051 | if (ret) |
5052 | goto abort; | ||
4999 | } | 5053 | } |
5000 | } else { | 5054 | } else { |
5001 | if (found_extent) { | 5055 | if (found_extent) { |
@@ -5012,19 +5066,27 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5012 | 5066 | ||
5013 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], | 5067 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], |
5014 | num_to_del); | 5068 | num_to_del); |
5015 | BUG_ON(ret); | 5069 | if (ret) |
5070 | goto abort; | ||
5016 | btrfs_release_path(path); | 5071 | btrfs_release_path(path); |
5017 | 5072 | ||
5018 | if (is_data) { | 5073 | if (is_data) { |
5019 | ret = btrfs_del_csums(trans, root, bytenr, num_bytes); | 5074 | ret = btrfs_del_csums(trans, root, bytenr, num_bytes); |
5020 | BUG_ON(ret); | 5075 | if (ret) |
5076 | goto abort; | ||
5021 | } | 5077 | } |
5022 | 5078 | ||
5023 | ret = update_block_group(trans, root, bytenr, num_bytes, 0); | 5079 | ret = update_block_group(trans, root, bytenr, num_bytes, 0); |
5024 | BUG_ON(ret); | 5080 | if (ret) |
5081 | goto abort; | ||
5025 | } | 5082 | } |
5083 | out: | ||
5026 | btrfs_free_path(path); | 5084 | btrfs_free_path(path); |
5027 | return ret; | 5085 | return ret; |
5086 | |||
5087 | abort: | ||
5088 | btrfs_abort_transaction(trans, extent_root, ret); | ||
5089 | goto out; | ||
5028 | } | 5090 | } |
5029 | 5091 | ||
5030 | /* | 5092 | /* |
@@ -5120,7 +5182,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
5120 | parent, root->root_key.objectid, | 5182 | parent, root->root_key.objectid, |
5121 | btrfs_header_level(buf), | 5183 | btrfs_header_level(buf), |
5122 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); | 5184 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); |
5123 | BUG_ON(ret); | 5185 | BUG_ON(ret); /* -ENOMEM */ |
5124 | } | 5186 | } |
5125 | 5187 | ||
5126 | if (!last_ref) | 5188 | if (!last_ref) |
@@ -5154,6 +5216,7 @@ out: | |||
5154 | btrfs_put_block_group(cache); | 5216 | btrfs_put_block_group(cache); |
5155 | } | 5217 | } |
5156 | 5218 | ||
5219 | /* Can return -ENOMEM */ | ||
5157 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 5220 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
5158 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, | 5221 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, |
5159 | u64 owner, u64 offset, int for_cow) | 5222 | u64 owner, u64 offset, int for_cow) |
@@ -5175,14 +5238,12 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
5175 | num_bytes, | 5238 | num_bytes, |
5176 | parent, root_objectid, (int)owner, | 5239 | parent, root_objectid, (int)owner, |
5177 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); | 5240 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); |
5178 | BUG_ON(ret); | ||
5179 | } else { | 5241 | } else { |
5180 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, | 5242 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
5181 | num_bytes, | 5243 | num_bytes, |
5182 | parent, root_objectid, owner, | 5244 | parent, root_objectid, owner, |
5183 | offset, BTRFS_DROP_DELAYED_REF, | 5245 | offset, BTRFS_DROP_DELAYED_REF, |
5184 | NULL, for_cow); | 5246 | NULL, for_cow); |
5185 | BUG_ON(ret); | ||
5186 | } | 5247 | } |
5187 | return ret; | 5248 | return ret; |
5188 | } | 5249 | } |
@@ -5412,7 +5473,8 @@ have_block_group: | |||
5412 | found_uncached_bg = true; | 5473 | found_uncached_bg = true; |
5413 | ret = cache_block_group(block_group, trans, | 5474 | ret = cache_block_group(block_group, trans, |
5414 | orig_root, 0); | 5475 | orig_root, 0); |
5415 | BUG_ON(ret); | 5476 | BUG_ON(ret < 0); |
5477 | ret = 0; | ||
5416 | } | 5478 | } |
5417 | 5479 | ||
5418 | if (unlikely(block_group->ro)) | 5480 | if (unlikely(block_group->ro)) |
@@ -5631,6 +5693,11 @@ loop: | |||
5631 | ret = do_chunk_alloc(trans, root, num_bytes + | 5693 | ret = do_chunk_alloc(trans, root, num_bytes + |
5632 | 2 * 1024 * 1024, data, | 5694 | 2 * 1024 * 1024, data, |
5633 | CHUNK_ALLOC_LIMITED); | 5695 | CHUNK_ALLOC_LIMITED); |
5696 | if (ret < 0) { | ||
5697 | btrfs_abort_transaction(trans, | ||
5698 | root, ret); | ||
5699 | goto out; | ||
5700 | } | ||
5634 | allowed_chunk_alloc = 0; | 5701 | allowed_chunk_alloc = 0; |
5635 | if (ret == 1) | 5702 | if (ret == 1) |
5636 | done_chunk_alloc = 1; | 5703 | done_chunk_alloc = 1; |
@@ -5659,6 +5726,7 @@ loop: | |||
5659 | } else if (ins->objectid) { | 5726 | } else if (ins->objectid) { |
5660 | ret = 0; | 5727 | ret = 0; |
5661 | } | 5728 | } |
5729 | out: | ||
5662 | 5730 | ||
5663 | return ret; | 5731 | return ret; |
5664 | } | 5732 | } |
@@ -5723,10 +5791,15 @@ again: | |||
5723 | * the only place that sets empty_size is btrfs_realloc_node, which | 5791 | * the only place that sets empty_size is btrfs_realloc_node, which |
5724 | * is not called recursively on allocations | 5792 | * is not called recursively on allocations |
5725 | */ | 5793 | */ |
5726 | if (empty_size || root->ref_cows) | 5794 | if (empty_size || root->ref_cows) { |
5727 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 5795 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
5728 | num_bytes + 2 * 1024 * 1024, data, | 5796 | num_bytes + 2 * 1024 * 1024, data, |
5729 | CHUNK_ALLOC_NO_FORCE); | 5797 | CHUNK_ALLOC_NO_FORCE); |
5798 | if (ret < 0 && ret != -ENOSPC) { | ||
5799 | btrfs_abort_transaction(trans, root, ret); | ||
5800 | return ret; | ||
5801 | } | ||
5802 | } | ||
5730 | 5803 | ||
5731 | WARN_ON(num_bytes < root->sectorsize); | 5804 | WARN_ON(num_bytes < root->sectorsize); |
5732 | ret = find_free_extent(trans, root, num_bytes, empty_size, | 5805 | ret = find_free_extent(trans, root, num_bytes, empty_size, |
@@ -5737,8 +5810,12 @@ again: | |||
5737 | num_bytes = num_bytes >> 1; | 5810 | num_bytes = num_bytes >> 1; |
5738 | num_bytes = num_bytes & ~(root->sectorsize - 1); | 5811 | num_bytes = num_bytes & ~(root->sectorsize - 1); |
5739 | num_bytes = max(num_bytes, min_alloc_size); | 5812 | num_bytes = max(num_bytes, min_alloc_size); |
5740 | do_chunk_alloc(trans, root->fs_info->extent_root, | 5813 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
5741 | num_bytes, data, CHUNK_ALLOC_FORCE); | 5814 | num_bytes, data, CHUNK_ALLOC_FORCE); |
5815 | if (ret < 0 && ret != -ENOSPC) { | ||
5816 | btrfs_abort_transaction(trans, root, ret); | ||
5817 | return ret; | ||
5818 | } | ||
5742 | if (num_bytes == min_alloc_size) | 5819 | if (num_bytes == min_alloc_size) |
5743 | final_tried = true; | 5820 | final_tried = true; |
5744 | goto again; | 5821 | goto again; |
@@ -5749,7 +5826,8 @@ again: | |||
5749 | printk(KERN_ERR "btrfs allocation failed flags %llu, " | 5826 | printk(KERN_ERR "btrfs allocation failed flags %llu, " |
5750 | "wanted %llu\n", (unsigned long long)data, | 5827 | "wanted %llu\n", (unsigned long long)data, |
5751 | (unsigned long long)num_bytes); | 5828 | (unsigned long long)num_bytes); |
5752 | dump_space_info(sinfo, num_bytes, 1); | 5829 | if (sinfo) |
5830 | dump_space_info(sinfo, num_bytes, 1); | ||
5753 | } | 5831 | } |
5754 | } | 5832 | } |
5755 | 5833 | ||
@@ -5828,7 +5906,10 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
5828 | path->leave_spinning = 1; | 5906 | path->leave_spinning = 1; |
5829 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, | 5907 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, |
5830 | ins, size); | 5908 | ins, size); |
5831 | BUG_ON(ret); | 5909 | if (ret) { |
5910 | btrfs_free_path(path); | ||
5911 | return ret; | ||
5912 | } | ||
5832 | 5913 | ||
5833 | leaf = path->nodes[0]; | 5914 | leaf = path->nodes[0]; |
5834 | extent_item = btrfs_item_ptr(leaf, path->slots[0], | 5915 | extent_item = btrfs_item_ptr(leaf, path->slots[0], |
@@ -5858,7 +5939,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
5858 | btrfs_free_path(path); | 5939 | btrfs_free_path(path); |
5859 | 5940 | ||
5860 | ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); | 5941 | ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); |
5861 | if (ret) { | 5942 | if (ret) { /* -ENOENT, logic error */ |
5862 | printk(KERN_ERR "btrfs update block group failed for %llu " | 5943 | printk(KERN_ERR "btrfs update block group failed for %llu " |
5863 | "%llu\n", (unsigned long long)ins->objectid, | 5944 | "%llu\n", (unsigned long long)ins->objectid, |
5864 | (unsigned long long)ins->offset); | 5945 | (unsigned long long)ins->offset); |
@@ -5889,7 +5970,10 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
5889 | path->leave_spinning = 1; | 5970 | path->leave_spinning = 1; |
5890 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, | 5971 | ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, |
5891 | ins, size); | 5972 | ins, size); |
5892 | BUG_ON(ret); | 5973 | if (ret) { |
5974 | btrfs_free_path(path); | ||
5975 | return ret; | ||
5976 | } | ||
5893 | 5977 | ||
5894 | leaf = path->nodes[0]; | 5978 | leaf = path->nodes[0]; |
5895 | extent_item = btrfs_item_ptr(leaf, path->slots[0], | 5979 | extent_item = btrfs_item_ptr(leaf, path->slots[0], |
@@ -5919,7 +6003,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, | |||
5919 | btrfs_free_path(path); | 6003 | btrfs_free_path(path); |
5920 | 6004 | ||
5921 | ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); | 6005 | ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); |
5922 | if (ret) { | 6006 | if (ret) { /* -ENOENT, logic error */ |
5923 | printk(KERN_ERR "btrfs update block group failed for %llu " | 6007 | printk(KERN_ERR "btrfs update block group failed for %llu " |
5924 | "%llu\n", (unsigned long long)ins->objectid, | 6008 | "%llu\n", (unsigned long long)ins->objectid, |
5925 | (unsigned long long)ins->offset); | 6009 | (unsigned long long)ins->offset); |
@@ -5967,28 +6051,28 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
5967 | if (!caching_ctl) { | 6051 | if (!caching_ctl) { |
5968 | BUG_ON(!block_group_cache_done(block_group)); | 6052 | BUG_ON(!block_group_cache_done(block_group)); |
5969 | ret = btrfs_remove_free_space(block_group, start, num_bytes); | 6053 | ret = btrfs_remove_free_space(block_group, start, num_bytes); |
5970 | BUG_ON(ret); | 6054 | BUG_ON(ret); /* -ENOMEM */ |
5971 | } else { | 6055 | } else { |
5972 | mutex_lock(&caching_ctl->mutex); | 6056 | mutex_lock(&caching_ctl->mutex); |
5973 | 6057 | ||
5974 | if (start >= caching_ctl->progress) { | 6058 | if (start >= caching_ctl->progress) { |
5975 | ret = add_excluded_extent(root, start, num_bytes); | 6059 | ret = add_excluded_extent(root, start, num_bytes); |
5976 | BUG_ON(ret); | 6060 | BUG_ON(ret); /* -ENOMEM */ |
5977 | } else if (start + num_bytes <= caching_ctl->progress) { | 6061 | } else if (start + num_bytes <= caching_ctl->progress) { |
5978 | ret = btrfs_remove_free_space(block_group, | 6062 | ret = btrfs_remove_free_space(block_group, |
5979 | start, num_bytes); | 6063 | start, num_bytes); |
5980 | BUG_ON(ret); | 6064 | BUG_ON(ret); /* -ENOMEM */ |
5981 | } else { | 6065 | } else { |
5982 | num_bytes = caching_ctl->progress - start; | 6066 | num_bytes = caching_ctl->progress - start; |
5983 | ret = btrfs_remove_free_space(block_group, | 6067 | ret = btrfs_remove_free_space(block_group, |
5984 | start, num_bytes); | 6068 | start, num_bytes); |
5985 | BUG_ON(ret); | 6069 | BUG_ON(ret); /* -ENOMEM */ |
5986 | 6070 | ||
5987 | start = caching_ctl->progress; | 6071 | start = caching_ctl->progress; |
5988 | num_bytes = ins->objectid + ins->offset - | 6072 | num_bytes = ins->objectid + ins->offset - |
5989 | caching_ctl->progress; | 6073 | caching_ctl->progress; |
5990 | ret = add_excluded_extent(root, start, num_bytes); | 6074 | ret = add_excluded_extent(root, start, num_bytes); |
5991 | BUG_ON(ret); | 6075 | BUG_ON(ret); /* -ENOMEM */ |
5992 | } | 6076 | } |
5993 | 6077 | ||
5994 | mutex_unlock(&caching_ctl->mutex); | 6078 | mutex_unlock(&caching_ctl->mutex); |
@@ -5997,7 +6081,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
5997 | 6081 | ||
5998 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, | 6082 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, |
5999 | RESERVE_ALLOC_NO_ACCOUNT); | 6083 | RESERVE_ALLOC_NO_ACCOUNT); |
6000 | BUG_ON(ret); | 6084 | BUG_ON(ret); /* logic error */ |
6001 | btrfs_put_block_group(block_group); | 6085 | btrfs_put_block_group(block_group); |
6002 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, | 6086 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, |
6003 | 0, owner, offset, ins, 1); | 6087 | 0, owner, offset, ins, 1); |
@@ -6134,7 +6218,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
6134 | 6218 | ||
6135 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, | 6219 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, |
6136 | blocksize, level); | 6220 | blocksize, level); |
6137 | BUG_ON(IS_ERR(buf)); | 6221 | BUG_ON(IS_ERR(buf)); /* -ENOMEM */ |
6138 | 6222 | ||
6139 | if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) { | 6223 | if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) { |
6140 | if (parent == 0) | 6224 | if (parent == 0) |
@@ -6146,7 +6230,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
6146 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { | 6230 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { |
6147 | struct btrfs_delayed_extent_op *extent_op; | 6231 | struct btrfs_delayed_extent_op *extent_op; |
6148 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | 6232 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); |
6149 | BUG_ON(!extent_op); | 6233 | BUG_ON(!extent_op); /* -ENOMEM */ |
6150 | if (key) | 6234 | if (key) |
6151 | memcpy(&extent_op->key, key, sizeof(extent_op->key)); | 6235 | memcpy(&extent_op->key, key, sizeof(extent_op->key)); |
6152 | else | 6236 | else |
@@ -6161,7 +6245,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
6161 | ins.offset, parent, root_objectid, | 6245 | ins.offset, parent, root_objectid, |
6162 | level, BTRFS_ADD_DELAYED_EXTENT, | 6246 | level, BTRFS_ADD_DELAYED_EXTENT, |
6163 | extent_op, for_cow); | 6247 | extent_op, for_cow); |
6164 | BUG_ON(ret); | 6248 | BUG_ON(ret); /* -ENOMEM */ |
6165 | } | 6249 | } |
6166 | return buf; | 6250 | return buf; |
6167 | } | 6251 | } |
@@ -6231,7 +6315,9 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, | |||
6231 | /* We don't lock the tree block, it's OK to be racy here */ | 6315 | /* We don't lock the tree block, it's OK to be racy here */ |
6232 | ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, | 6316 | ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, |
6233 | &refs, &flags); | 6317 | &refs, &flags); |
6234 | BUG_ON(ret); | 6318 | /* We don't care about errors in readahead. */ |
6319 | if (ret < 0) | ||
6320 | continue; | ||
6235 | BUG_ON(refs == 0); | 6321 | BUG_ON(refs == 0); |
6236 | 6322 | ||
6237 | if (wc->stage == DROP_REFERENCE) { | 6323 | if (wc->stage == DROP_REFERENCE) { |
@@ -6298,7 +6384,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, | |||
6298 | eb->start, eb->len, | 6384 | eb->start, eb->len, |
6299 | &wc->refs[level], | 6385 | &wc->refs[level], |
6300 | &wc->flags[level]); | 6386 | &wc->flags[level]); |
6301 | BUG_ON(ret); | 6387 | BUG_ON(ret == -ENOMEM); |
6388 | if (ret) | ||
6389 | return ret; | ||
6302 | BUG_ON(wc->refs[level] == 0); | 6390 | BUG_ON(wc->refs[level] == 0); |
6303 | } | 6391 | } |
6304 | 6392 | ||
@@ -6317,12 +6405,12 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, | |||
6317 | if (!(wc->flags[level] & flag)) { | 6405 | if (!(wc->flags[level] & flag)) { |
6318 | BUG_ON(!path->locks[level]); | 6406 | BUG_ON(!path->locks[level]); |
6319 | ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc); | 6407 | ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc); |
6320 | BUG_ON(ret); | 6408 | BUG_ON(ret); /* -ENOMEM */ |
6321 | ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); | 6409 | ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); |
6322 | BUG_ON(ret); | 6410 | BUG_ON(ret); /* -ENOMEM */ |
6323 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, | 6411 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, |
6324 | eb->len, flag, 0); | 6412 | eb->len, flag, 0); |
6325 | BUG_ON(ret); | 6413 | BUG_ON(ret); /* -ENOMEM */ |
6326 | wc->flags[level] |= flag; | 6414 | wc->flags[level] |= flag; |
6327 | } | 6415 | } |
6328 | 6416 | ||
@@ -6394,7 +6482,11 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
6394 | ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, | 6482 | ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, |
6395 | &wc->refs[level - 1], | 6483 | &wc->refs[level - 1], |
6396 | &wc->flags[level - 1]); | 6484 | &wc->flags[level - 1]); |
6397 | BUG_ON(ret); | 6485 | if (ret < 0) { |
6486 | btrfs_tree_unlock(next); | ||
6487 | return ret; | ||
6488 | } | ||
6489 | |||
6398 | BUG_ON(wc->refs[level - 1] == 0); | 6490 | BUG_ON(wc->refs[level - 1] == 0); |
6399 | *lookup_info = 0; | 6491 | *lookup_info = 0; |
6400 | 6492 | ||
@@ -6463,7 +6555,7 @@ skip: | |||
6463 | 6555 | ||
6464 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, | 6556 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, |
6465 | root->root_key.objectid, level - 1, 0, 0); | 6557 | root->root_key.objectid, level - 1, 0, 0); |
6466 | BUG_ON(ret); | 6558 | BUG_ON(ret); /* -ENOMEM */ |
6467 | } | 6559 | } |
6468 | btrfs_tree_unlock(next); | 6560 | btrfs_tree_unlock(next); |
6469 | free_extent_buffer(next); | 6561 | free_extent_buffer(next); |
@@ -6521,7 +6613,10 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
6521 | eb->start, eb->len, | 6613 | eb->start, eb->len, |
6522 | &wc->refs[level], | 6614 | &wc->refs[level], |
6523 | &wc->flags[level]); | 6615 | &wc->flags[level]); |
6524 | BUG_ON(ret); | 6616 | if (ret < 0) { |
6617 | btrfs_tree_unlock_rw(eb, path->locks[level]); | ||
6618 | return ret; | ||
6619 | } | ||
6525 | BUG_ON(wc->refs[level] == 0); | 6620 | BUG_ON(wc->refs[level] == 0); |
6526 | if (wc->refs[level] == 1) { | 6621 | if (wc->refs[level] == 1) { |
6527 | btrfs_tree_unlock_rw(eb, path->locks[level]); | 6622 | btrfs_tree_unlock_rw(eb, path->locks[level]); |
@@ -6541,7 +6636,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
6541 | else | 6636 | else |
6542 | ret = btrfs_dec_ref(trans, root, eb, 0, | 6637 | ret = btrfs_dec_ref(trans, root, eb, 0, |
6543 | wc->for_reloc); | 6638 | wc->for_reloc); |
6544 | BUG_ON(ret); | 6639 | BUG_ON(ret); /* -ENOMEM */ |
6545 | } | 6640 | } |
6546 | /* make block locked assertion in clean_tree_block happy */ | 6641 | /* make block locked assertion in clean_tree_block happy */ |
6547 | if (!path->locks[level] && | 6642 | if (!path->locks[level] && |
@@ -6650,7 +6745,7 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
6650 | * also make sure backrefs for the shared block and all lower level | 6745 | * also make sure backrefs for the shared block and all lower level |
6651 | * blocks are properly updated. | 6746 | * blocks are properly updated. |
6652 | */ | 6747 | */ |
6653 | void btrfs_drop_snapshot(struct btrfs_root *root, | 6748 | int btrfs_drop_snapshot(struct btrfs_root *root, |
6654 | struct btrfs_block_rsv *block_rsv, int update_ref, | 6749 | struct btrfs_block_rsv *block_rsv, int update_ref, |
6655 | int for_reloc) | 6750 | int for_reloc) |
6656 | { | 6751 | { |
@@ -6678,7 +6773,10 @@ void btrfs_drop_snapshot(struct btrfs_root *root, | |||
6678 | } | 6773 | } |
6679 | 6774 | ||
6680 | trans = btrfs_start_transaction(tree_root, 0); | 6775 | trans = btrfs_start_transaction(tree_root, 0); |
6681 | BUG_ON(IS_ERR(trans)); | 6776 | if (IS_ERR(trans)) { |
6777 | err = PTR_ERR(trans); | ||
6778 | goto out_free; | ||
6779 | } | ||
6682 | 6780 | ||
6683 | if (block_rsv) | 6781 | if (block_rsv) |
6684 | trans->block_rsv = block_rsv; | 6782 | trans->block_rsv = block_rsv; |
@@ -6703,7 +6801,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, | |||
6703 | path->lowest_level = 0; | 6801 | path->lowest_level = 0; |
6704 | if (ret < 0) { | 6802 | if (ret < 0) { |
6705 | err = ret; | 6803 | err = ret; |
6706 | goto out_free; | 6804 | goto out_end_trans; |
6707 | } | 6805 | } |
6708 | WARN_ON(ret > 0); | 6806 | WARN_ON(ret > 0); |
6709 | 6807 | ||
@@ -6723,7 +6821,10 @@ void btrfs_drop_snapshot(struct btrfs_root *root, | |||
6723 | path->nodes[level]->len, | 6821 | path->nodes[level]->len, |
6724 | &wc->refs[level], | 6822 | &wc->refs[level], |
6725 | &wc->flags[level]); | 6823 | &wc->flags[level]); |
6726 | BUG_ON(ret); | 6824 | if (ret < 0) { |
6825 | err = ret; | ||
6826 | goto out_end_trans; | ||
6827 | } | ||
6727 | BUG_ON(wc->refs[level] == 0); | 6828 | BUG_ON(wc->refs[level] == 0); |
6728 | 6829 | ||
6729 | if (level == root_item->drop_level) | 6830 | if (level == root_item->drop_level) |
@@ -6774,26 +6875,40 @@ void btrfs_drop_snapshot(struct btrfs_root *root, | |||
6774 | ret = btrfs_update_root(trans, tree_root, | 6875 | ret = btrfs_update_root(trans, tree_root, |
6775 | &root->root_key, | 6876 | &root->root_key, |
6776 | root_item); | 6877 | root_item); |
6777 | BUG_ON(ret); | 6878 | if (ret) { |
6879 | btrfs_abort_transaction(trans, tree_root, ret); | ||
6880 | err = ret; | ||
6881 | goto out_end_trans; | ||
6882 | } | ||
6778 | 6883 | ||
6779 | btrfs_end_transaction_throttle(trans, tree_root); | 6884 | btrfs_end_transaction_throttle(trans, tree_root); |
6780 | trans = btrfs_start_transaction(tree_root, 0); | 6885 | trans = btrfs_start_transaction(tree_root, 0); |
6781 | BUG_ON(IS_ERR(trans)); | 6886 | if (IS_ERR(trans)) { |
6887 | err = PTR_ERR(trans); | ||
6888 | goto out_free; | ||
6889 | } | ||
6782 | if (block_rsv) | 6890 | if (block_rsv) |
6783 | trans->block_rsv = block_rsv; | 6891 | trans->block_rsv = block_rsv; |
6784 | } | 6892 | } |
6785 | } | 6893 | } |
6786 | btrfs_release_path(path); | 6894 | btrfs_release_path(path); |
6787 | BUG_ON(err); | 6895 | if (err) |
6896 | goto out_end_trans; | ||
6788 | 6897 | ||
6789 | ret = btrfs_del_root(trans, tree_root, &root->root_key); | 6898 | ret = btrfs_del_root(trans, tree_root, &root->root_key); |
6790 | BUG_ON(ret); | 6899 | if (ret) { |
6900 | btrfs_abort_transaction(trans, tree_root, ret); | ||
6901 | goto out_end_trans; | ||
6902 | } | ||
6791 | 6903 | ||
6792 | if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { | 6904 | if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { |
6793 | ret = btrfs_find_last_root(tree_root, root->root_key.objectid, | 6905 | ret = btrfs_find_last_root(tree_root, root->root_key.objectid, |
6794 | NULL, NULL); | 6906 | NULL, NULL); |
6795 | BUG_ON(ret < 0); | 6907 | if (ret < 0) { |
6796 | if (ret > 0) { | 6908 | btrfs_abort_transaction(trans, tree_root, ret); |
6909 | err = ret; | ||
6910 | goto out_end_trans; | ||
6911 | } else if (ret > 0) { | ||
6797 | /* if we fail to delete the orphan item this time | 6912 | /* if we fail to delete the orphan item this time |
6798 | * around, it'll get picked up the next time. | 6913 | * around, it'll get picked up the next time. |
6799 | * | 6914 | * |
@@ -6811,14 +6926,15 @@ void btrfs_drop_snapshot(struct btrfs_root *root, | |||
6811 | free_extent_buffer(root->commit_root); | 6926 | free_extent_buffer(root->commit_root); |
6812 | kfree(root); | 6927 | kfree(root); |
6813 | } | 6928 | } |
6814 | out_free: | 6929 | out_end_trans: |
6815 | btrfs_end_transaction_throttle(trans, tree_root); | 6930 | btrfs_end_transaction_throttle(trans, tree_root); |
6931 | out_free: | ||
6816 | kfree(wc); | 6932 | kfree(wc); |
6817 | btrfs_free_path(path); | 6933 | btrfs_free_path(path); |
6818 | out: | 6934 | out: |
6819 | if (err) | 6935 | if (err) |
6820 | btrfs_std_error(root->fs_info, err); | 6936 | btrfs_std_error(root->fs_info, err); |
6821 | return; | 6937 | return err; |
6822 | } | 6938 | } |
6823 | 6939 | ||
6824 | /* | 6940 | /* |
@@ -7015,12 +7131,16 @@ int btrfs_set_block_group_ro(struct btrfs_root *root, | |||
7015 | BUG_ON(cache->ro); | 7131 | BUG_ON(cache->ro); |
7016 | 7132 | ||
7017 | trans = btrfs_join_transaction(root); | 7133 | trans = btrfs_join_transaction(root); |
7018 | BUG_ON(IS_ERR(trans)); | 7134 | if (IS_ERR(trans)) |
7135 | return PTR_ERR(trans); | ||
7019 | 7136 | ||
7020 | alloc_flags = update_block_group_flags(root, cache->flags); | 7137 | alloc_flags = update_block_group_flags(root, cache->flags); |
7021 | if (alloc_flags != cache->flags) | 7138 | if (alloc_flags != cache->flags) { |
7022 | do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, | 7139 | ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, |
7023 | CHUNK_ALLOC_FORCE); | 7140 | CHUNK_ALLOC_FORCE); |
7141 | if (ret < 0) | ||
7142 | goto out; | ||
7143 | } | ||
7024 | 7144 | ||
7025 | ret = set_block_group_ro(cache, 0); | 7145 | ret = set_block_group_ro(cache, 0); |
7026 | if (!ret) | 7146 | if (!ret) |
@@ -7100,7 +7220,7 @@ u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) | |||
7100 | return free_bytes; | 7220 | return free_bytes; |
7101 | } | 7221 | } |
7102 | 7222 | ||
7103 | int btrfs_set_block_group_rw(struct btrfs_root *root, | 7223 | void btrfs_set_block_group_rw(struct btrfs_root *root, |
7104 | struct btrfs_block_group_cache *cache) | 7224 | struct btrfs_block_group_cache *cache) |
7105 | { | 7225 | { |
7106 | struct btrfs_space_info *sinfo = cache->space_info; | 7226 | struct btrfs_space_info *sinfo = cache->space_info; |
@@ -7116,7 +7236,6 @@ int btrfs_set_block_group_rw(struct btrfs_root *root, | |||
7116 | cache->ro = 0; | 7236 | cache->ro = 0; |
7117 | spin_unlock(&cache->lock); | 7237 | spin_unlock(&cache->lock); |
7118 | spin_unlock(&sinfo->lock); | 7238 | spin_unlock(&sinfo->lock); |
7119 | return 0; | ||
7120 | } | 7239 | } |
7121 | 7240 | ||
7122 | /* | 7241 | /* |
@@ -7484,7 +7603,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
7484 | ret = update_space_info(info, cache->flags, found_key.offset, | 7603 | ret = update_space_info(info, cache->flags, found_key.offset, |
7485 | btrfs_block_group_used(&cache->item), | 7604 | btrfs_block_group_used(&cache->item), |
7486 | &space_info); | 7605 | &space_info); |
7487 | BUG_ON(ret); | 7606 | BUG_ON(ret); /* -ENOMEM */ |
7488 | cache->space_info = space_info; | 7607 | cache->space_info = space_info; |
7489 | spin_lock(&cache->space_info->lock); | 7608 | spin_lock(&cache->space_info->lock); |
7490 | cache->space_info->bytes_readonly += cache->bytes_super; | 7609 | cache->space_info->bytes_readonly += cache->bytes_super; |
@@ -7493,7 +7612,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
7493 | __link_block_group(space_info, cache); | 7612 | __link_block_group(space_info, cache); |
7494 | 7613 | ||
7495 | ret = btrfs_add_block_group_cache(root->fs_info, cache); | 7614 | ret = btrfs_add_block_group_cache(root->fs_info, cache); |
7496 | BUG_ON(ret); | 7615 | BUG_ON(ret); /* Logic error */ |
7497 | 7616 | ||
7498 | set_avail_alloc_bits(root->fs_info, cache->flags); | 7617 | set_avail_alloc_bits(root->fs_info, cache->flags); |
7499 | if (btrfs_chunk_readonly(root, cache->key.objectid)) | 7618 | if (btrfs_chunk_readonly(root, cache->key.objectid)) |
@@ -7575,7 +7694,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
7575 | 7694 | ||
7576 | ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, | 7695 | ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, |
7577 | &cache->space_info); | 7696 | &cache->space_info); |
7578 | BUG_ON(ret); | 7697 | BUG_ON(ret); /* -ENOMEM */ |
7579 | update_global_block_rsv(root->fs_info); | 7698 | update_global_block_rsv(root->fs_info); |
7580 | 7699 | ||
7581 | spin_lock(&cache->space_info->lock); | 7700 | spin_lock(&cache->space_info->lock); |
@@ -7585,11 +7704,14 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
7585 | __link_block_group(cache->space_info, cache); | 7704 | __link_block_group(cache->space_info, cache); |
7586 | 7705 | ||
7587 | ret = btrfs_add_block_group_cache(root->fs_info, cache); | 7706 | ret = btrfs_add_block_group_cache(root->fs_info, cache); |
7588 | BUG_ON(ret); | 7707 | BUG_ON(ret); /* Logic error */ |
7589 | 7708 | ||
7590 | ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item, | 7709 | ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item, |
7591 | sizeof(cache->item)); | 7710 | sizeof(cache->item)); |
7592 | BUG_ON(ret); | 7711 | if (ret) { |
7712 | btrfs_abort_transaction(trans, extent_root, ret); | ||
7713 | return ret; | ||
7714 | } | ||
7593 | 7715 | ||
7594 | set_avail_alloc_bits(extent_root->fs_info, type); | 7716 | set_avail_alloc_bits(extent_root->fs_info, type); |
7595 | 7717 | ||
@@ -7670,7 +7792,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
7670 | inode = lookup_free_space_inode(tree_root, block_group, path); | 7792 | inode = lookup_free_space_inode(tree_root, block_group, path); |
7671 | if (!IS_ERR(inode)) { | 7793 | if (!IS_ERR(inode)) { |
7672 | ret = btrfs_orphan_add(trans, inode); | 7794 | ret = btrfs_orphan_add(trans, inode); |
7673 | BUG_ON(ret); | 7795 | if (ret) { |
7796 | btrfs_add_delayed_iput(inode); | ||
7797 | goto out; | ||
7798 | } | ||
7674 | clear_nlink(inode); | 7799 | clear_nlink(inode); |
7675 | /* One for the block groups ref */ | 7800 | /* One for the block groups ref */ |
7676 | spin_lock(&block_group->lock); | 7801 | spin_lock(&block_group->lock); |