aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c84
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);