diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 89 |
1 files changed, 76 insertions, 13 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 3e074dab2d57..3d551231caba 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -257,7 +257,8 @@ static int exclude_super_stripes(struct btrfs_root *root, | |||
257 | cache->bytes_super += stripe_len; | 257 | cache->bytes_super += stripe_len; |
258 | ret = add_excluded_extent(root, cache->key.objectid, | 258 | ret = add_excluded_extent(root, cache->key.objectid, |
259 | stripe_len); | 259 | stripe_len); |
260 | BUG_ON(ret); /* -ENOMEM */ | 260 | if (ret) |
261 | return ret; | ||
261 | } | 262 | } |
262 | 263 | ||
263 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { | 264 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { |
@@ -265,13 +266,17 @@ static int exclude_super_stripes(struct btrfs_root *root, | |||
265 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, | 266 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, |
266 | cache->key.objectid, bytenr, | 267 | cache->key.objectid, bytenr, |
267 | 0, &logical, &nr, &stripe_len); | 268 | 0, &logical, &nr, &stripe_len); |
268 | BUG_ON(ret); /* -ENOMEM */ | 269 | if (ret) |
270 | return ret; | ||
269 | 271 | ||
270 | while (nr--) { | 272 | while (nr--) { |
271 | cache->bytes_super += stripe_len; | 273 | cache->bytes_super += stripe_len; |
272 | ret = add_excluded_extent(root, logical[nr], | 274 | ret = add_excluded_extent(root, logical[nr], |
273 | stripe_len); | 275 | stripe_len); |
274 | BUG_ON(ret); /* -ENOMEM */ | 276 | if (ret) { |
277 | kfree(logical); | ||
278 | return ret; | ||
279 | } | ||
275 | } | 280 | } |
276 | 281 | ||
277 | kfree(logical); | 282 | kfree(logical); |
@@ -1467,8 +1472,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
1467 | if (ret && !insert) { | 1472 | if (ret && !insert) { |
1468 | err = -ENOENT; | 1473 | err = -ENOENT; |
1469 | goto out; | 1474 | goto out; |
1475 | } else if (ret) { | ||
1476 | err = -EIO; | ||
1477 | WARN_ON(1); | ||
1478 | goto out; | ||
1470 | } | 1479 | } |
1471 | BUG_ON(ret); /* Corruption */ | ||
1472 | 1480 | ||
1473 | leaf = path->nodes[0]; | 1481 | leaf = path->nodes[0]; |
1474 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 1482 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
@@ -4435,7 +4443,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
4435 | spin_lock(&sinfo->lock); | 4443 | spin_lock(&sinfo->lock); |
4436 | spin_lock(&block_rsv->lock); | 4444 | spin_lock(&block_rsv->lock); |
4437 | 4445 | ||
4438 | block_rsv->size = num_bytes; | 4446 | block_rsv->size = min_t(u64, num_bytes, 512 * 1024 * 1024); |
4439 | 4447 | ||
4440 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + | 4448 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + |
4441 | sinfo->bytes_reserved + sinfo->bytes_readonly + | 4449 | sinfo->bytes_reserved + sinfo->bytes_readonly + |
@@ -4790,14 +4798,49 @@ out_fail: | |||
4790 | * If the inodes csum_bytes is the same as the original | 4798 | * If the inodes csum_bytes is the same as the original |
4791 | * csum_bytes then we know we haven't raced with any free()ers | 4799 | * csum_bytes then we know we haven't raced with any free()ers |
4792 | * so we can just reduce our inodes csum bytes and carry on. | 4800 | * so we can just reduce our inodes csum bytes and carry on. |
4793 | * Otherwise we have to do the normal free thing to account for | ||
4794 | * the case that the free side didn't free up its reserve | ||
4795 | * because of this outstanding reservation. | ||
4796 | */ | 4801 | */ |
4797 | if (BTRFS_I(inode)->csum_bytes == csum_bytes) | 4802 | if (BTRFS_I(inode)->csum_bytes == csum_bytes) { |
4798 | calc_csum_metadata_size(inode, num_bytes, 0); | 4803 | calc_csum_metadata_size(inode, num_bytes, 0); |
4799 | else | 4804 | } else { |
4800 | to_free = calc_csum_metadata_size(inode, num_bytes, 0); | 4805 | u64 orig_csum_bytes = BTRFS_I(inode)->csum_bytes; |
4806 | u64 bytes; | ||
4807 | |||
4808 | /* | ||
4809 | * This is tricky, but first we need to figure out how much we | ||
4810 | * free'd from any free-ers that occured during this | ||
4811 | * reservation, so we reset ->csum_bytes to the csum_bytes | ||
4812 | * before we dropped our lock, and then call the free for the | ||
4813 | * number of bytes that were freed while we were trying our | ||
4814 | * reservation. | ||
4815 | */ | ||
4816 | bytes = csum_bytes - BTRFS_I(inode)->csum_bytes; | ||
4817 | BTRFS_I(inode)->csum_bytes = csum_bytes; | ||
4818 | to_free = calc_csum_metadata_size(inode, bytes, 0); | ||
4819 | |||
4820 | |||
4821 | /* | ||
4822 | * Now we need to see how much we would have freed had we not | ||
4823 | * been making this reservation and our ->csum_bytes were not | ||
4824 | * artificially inflated. | ||
4825 | */ | ||
4826 | BTRFS_I(inode)->csum_bytes = csum_bytes - num_bytes; | ||
4827 | bytes = csum_bytes - orig_csum_bytes; | ||
4828 | bytes = calc_csum_metadata_size(inode, bytes, 0); | ||
4829 | |||
4830 | /* | ||
4831 | * Now reset ->csum_bytes to what it should be. If bytes is | ||
4832 | * more than to_free then we would have free'd more space had we | ||
4833 | * not had an artificially high ->csum_bytes, so we need to free | ||
4834 | * the remainder. If bytes is the same or less then we don't | ||
4835 | * need to do anything, the other free-ers did the correct | ||
4836 | * thing. | ||
4837 | */ | ||
4838 | BTRFS_I(inode)->csum_bytes = orig_csum_bytes - num_bytes; | ||
4839 | if (bytes > to_free) | ||
4840 | to_free = bytes - to_free; | ||
4841 | else | ||
4842 | to_free = 0; | ||
4843 | } | ||
4801 | spin_unlock(&BTRFS_I(inode)->lock); | 4844 | spin_unlock(&BTRFS_I(inode)->lock); |
4802 | if (dropped) | 4845 | if (dropped) |
4803 | to_free += btrfs_calc_trans_metadata_size(root, dropped); | 4846 | to_free += btrfs_calc_trans_metadata_size(root, dropped); |
@@ -7944,7 +7987,17 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
7944 | * info has super bytes accounted for, otherwise we'll think | 7987 | * info has super bytes accounted for, otherwise we'll think |
7945 | * we have more space than we actually do. | 7988 | * we have more space than we actually do. |
7946 | */ | 7989 | */ |
7947 | exclude_super_stripes(root, cache); | 7990 | ret = exclude_super_stripes(root, cache); |
7991 | if (ret) { | ||
7992 | /* | ||
7993 | * We may have excluded something, so call this just in | ||
7994 | * case. | ||
7995 | */ | ||
7996 | free_excluded_extents(root, cache); | ||
7997 | kfree(cache->free_space_ctl); | ||
7998 | kfree(cache); | ||
7999 | goto error; | ||
8000 | } | ||
7948 | 8001 | ||
7949 | /* | 8002 | /* |
7950 | * check for two cases, either we are full, and therefore | 8003 | * check for two cases, either we are full, and therefore |
@@ -8086,7 +8139,17 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
8086 | 8139 | ||
8087 | cache->last_byte_to_unpin = (u64)-1; | 8140 | cache->last_byte_to_unpin = (u64)-1; |
8088 | cache->cached = BTRFS_CACHE_FINISHED; | 8141 | cache->cached = BTRFS_CACHE_FINISHED; |
8089 | exclude_super_stripes(root, cache); | 8142 | ret = exclude_super_stripes(root, cache); |
8143 | if (ret) { | ||
8144 | /* | ||
8145 | * We may have excluded something, so call this just in | ||
8146 | * case. | ||
8147 | */ | ||
8148 | free_excluded_extents(root, cache); | ||
8149 | kfree(cache->free_space_ctl); | ||
8150 | kfree(cache); | ||
8151 | return ret; | ||
8152 | } | ||
8090 | 8153 | ||
8091 | add_new_free_space(cache, root->fs_info, chunk_offset, | 8154 | add_new_free_space(cache, root->fs_info, chunk_offset, |
8092 | chunk_offset + size); | 8155 | chunk_offset + size); |