diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 84 |
1 files changed, 72 insertions, 12 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9ac2eca681eb..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); |
| @@ -4438,7 +4443,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
| 4438 | spin_lock(&sinfo->lock); | 4443 | spin_lock(&sinfo->lock); |
| 4439 | spin_lock(&block_rsv->lock); | 4444 | spin_lock(&block_rsv->lock); |
| 4440 | 4445 | ||
| 4441 | block_rsv->size = num_bytes; | 4446 | block_rsv->size = min_t(u64, num_bytes, 512 * 1024 * 1024); |
| 4442 | 4447 | ||
| 4443 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + | 4448 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + |
| 4444 | sinfo->bytes_reserved + sinfo->bytes_readonly + | 4449 | sinfo->bytes_reserved + sinfo->bytes_readonly + |
| @@ -4793,14 +4798,49 @@ out_fail: | |||
| 4793 | * If the inodes csum_bytes is the same as the original | 4798 | * If the inodes csum_bytes is the same as the original |
| 4794 | * 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 |
| 4795 | * 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. |
| 4796 | * Otherwise we have to do the normal free thing to account for | ||
| 4797 | * the case that the free side didn't free up its reserve | ||
| 4798 | * because of this outstanding reservation. | ||
| 4799 | */ | 4801 | */ |
| 4800 | if (BTRFS_I(inode)->csum_bytes == csum_bytes) | 4802 | if (BTRFS_I(inode)->csum_bytes == csum_bytes) { |
| 4801 | calc_csum_metadata_size(inode, num_bytes, 0); | 4803 | calc_csum_metadata_size(inode, num_bytes, 0); |
| 4802 | else | 4804 | } else { |
| 4803 | 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 | } | ||
| 4804 | spin_unlock(&BTRFS_I(inode)->lock); | 4844 | spin_unlock(&BTRFS_I(inode)->lock); |
| 4805 | if (dropped) | 4845 | if (dropped) |
| 4806 | to_free += btrfs_calc_trans_metadata_size(root, dropped); | 4846 | to_free += btrfs_calc_trans_metadata_size(root, dropped); |
| @@ -7947,7 +7987,17 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 7947 | * info has super bytes accounted for, otherwise we'll think | 7987 | * info has super bytes accounted for, otherwise we'll think |
| 7948 | * we have more space than we actually do. | 7988 | * we have more space than we actually do. |
| 7949 | */ | 7989 | */ |
| 7950 | 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 | } | ||
| 7951 | 8001 | ||
| 7952 | /* | 8002 | /* |
| 7953 | * check for two cases, either we are full, and therefore | 8003 | * check for two cases, either we are full, and therefore |
| @@ -8089,7 +8139,17 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
| 8089 | 8139 | ||
| 8090 | cache->last_byte_to_unpin = (u64)-1; | 8140 | cache->last_byte_to_unpin = (u64)-1; |
| 8091 | cache->cached = BTRFS_CACHE_FINISHED; | 8141 | cache->cached = BTRFS_CACHE_FINISHED; |
| 8092 | 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 | } | ||
| 8093 | 8153 | ||
| 8094 | add_new_free_space(cache, root->fs_info, chunk_offset, | 8154 | add_new_free_space(cache, root->fs_info, chunk_offset, |
| 8095 | chunk_offset + size); | 8155 | chunk_offset + size); |
