diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 90 |
1 files changed, 79 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 227e5815d838..b55269340cec 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3089,7 +3089,7 @@ static u64 get_alloc_profile(struct btrfs_root *root, u64 flags) | |||
3089 | return btrfs_reduce_alloc_profile(root, flags); | 3089 | return btrfs_reduce_alloc_profile(root, flags); |
3090 | } | 3090 | } |
3091 | 3091 | ||
3092 | static u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data) | 3092 | u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data) |
3093 | { | 3093 | { |
3094 | u64 flags; | 3094 | u64 flags; |
3095 | 3095 | ||
@@ -3161,8 +3161,12 @@ alloc: | |||
3161 | bytes + 2 * 1024 * 1024, | 3161 | bytes + 2 * 1024 * 1024, |
3162 | alloc_target, 0); | 3162 | alloc_target, 0); |
3163 | btrfs_end_transaction(trans, root); | 3163 | btrfs_end_transaction(trans, root); |
3164 | if (ret < 0) | 3164 | if (ret < 0) { |
3165 | return ret; | 3165 | if (ret != -ENOSPC) |
3166 | return ret; | ||
3167 | else | ||
3168 | goto commit_trans; | ||
3169 | } | ||
3166 | 3170 | ||
3167 | if (!data_sinfo) { | 3171 | if (!data_sinfo) { |
3168 | btrfs_set_inode_space_info(root, inode); | 3172 | btrfs_set_inode_space_info(root, inode); |
@@ -3173,6 +3177,7 @@ alloc: | |||
3173 | spin_unlock(&data_sinfo->lock); | 3177 | spin_unlock(&data_sinfo->lock); |
3174 | 3178 | ||
3175 | /* commit the current transaction and try again */ | 3179 | /* commit the current transaction and try again */ |
3180 | commit_trans: | ||
3176 | if (!committed && !root->fs_info->open_ioctl_trans) { | 3181 | if (!committed && !root->fs_info->open_ioctl_trans) { |
3177 | committed = 1; | 3182 | committed = 1; |
3178 | trans = btrfs_join_transaction(root, 1); | 3183 | trans = btrfs_join_transaction(root, 1); |
@@ -3721,11 +3726,6 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans, | |||
3721 | return 0; | 3726 | return 0; |
3722 | } | 3727 | } |
3723 | 3728 | ||
3724 | WARN_ON(1); | ||
3725 | printk(KERN_INFO"block_rsv size %llu reserved %llu freed %llu %llu\n", | ||
3726 | block_rsv->size, block_rsv->reserved, | ||
3727 | block_rsv->freed[0], block_rsv->freed[1]); | ||
3728 | |||
3729 | return -ENOSPC; | 3729 | return -ENOSPC; |
3730 | } | 3730 | } |
3731 | 3731 | ||
@@ -7970,13 +7970,14 @@ static int set_block_group_ro(struct btrfs_block_group_cache *cache) | |||
7970 | 7970 | ||
7971 | if (sinfo->bytes_used + sinfo->bytes_reserved + sinfo->bytes_pinned + | 7971 | if (sinfo->bytes_used + sinfo->bytes_reserved + sinfo->bytes_pinned + |
7972 | sinfo->bytes_may_use + sinfo->bytes_readonly + | 7972 | sinfo->bytes_may_use + sinfo->bytes_readonly + |
7973 | cache->reserved_pinned + num_bytes < sinfo->total_bytes) { | 7973 | cache->reserved_pinned + num_bytes <= sinfo->total_bytes) { |
7974 | sinfo->bytes_readonly += num_bytes; | 7974 | sinfo->bytes_readonly += num_bytes; |
7975 | sinfo->bytes_reserved += cache->reserved_pinned; | 7975 | sinfo->bytes_reserved += cache->reserved_pinned; |
7976 | cache->reserved_pinned = 0; | 7976 | cache->reserved_pinned = 0; |
7977 | cache->ro = 1; | 7977 | cache->ro = 1; |
7978 | ret = 0; | 7978 | ret = 0; |
7979 | } | 7979 | } |
7980 | |||
7980 | spin_unlock(&cache->lock); | 7981 | spin_unlock(&cache->lock); |
7981 | spin_unlock(&sinfo->lock); | 7982 | spin_unlock(&sinfo->lock); |
7982 | return ret; | 7983 | return ret; |
@@ -8012,6 +8013,62 @@ out: | |||
8012 | return ret; | 8013 | return ret; |
8013 | } | 8014 | } |
8014 | 8015 | ||
8016 | /* | ||
8017 | * helper to account the unused space of all the readonly block group in the | ||
8018 | * list. takes mirrors into account. | ||
8019 | */ | ||
8020 | static u64 __btrfs_get_ro_block_group_free_space(struct list_head *groups_list) | ||
8021 | { | ||
8022 | struct btrfs_block_group_cache *block_group; | ||
8023 | u64 free_bytes = 0; | ||
8024 | int factor; | ||
8025 | |||
8026 | list_for_each_entry(block_group, groups_list, list) { | ||
8027 | spin_lock(&block_group->lock); | ||
8028 | |||
8029 | if (!block_group->ro) { | ||
8030 | spin_unlock(&block_group->lock); | ||
8031 | continue; | ||
8032 | } | ||
8033 | |||
8034 | if (block_group->flags & (BTRFS_BLOCK_GROUP_RAID1 | | ||
8035 | BTRFS_BLOCK_GROUP_RAID10 | | ||
8036 | BTRFS_BLOCK_GROUP_DUP)) | ||
8037 | factor = 2; | ||
8038 | else | ||
8039 | factor = 1; | ||
8040 | |||
8041 | free_bytes += (block_group->key.offset - | ||
8042 | btrfs_block_group_used(&block_group->item)) * | ||
8043 | factor; | ||
8044 | |||
8045 | spin_unlock(&block_group->lock); | ||
8046 | } | ||
8047 | |||
8048 | return free_bytes; | ||
8049 | } | ||
8050 | |||
8051 | /* | ||
8052 | * helper to account the unused space of all the readonly block group in the | ||
8053 | * space_info. takes mirrors into account. | ||
8054 | */ | ||
8055 | u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) | ||
8056 | { | ||
8057 | int i; | ||
8058 | u64 free_bytes = 0; | ||
8059 | |||
8060 | spin_lock(&sinfo->lock); | ||
8061 | |||
8062 | for(i = 0; i < BTRFS_NR_RAID_TYPES; i++) | ||
8063 | if (!list_empty(&sinfo->block_groups[i])) | ||
8064 | free_bytes += __btrfs_get_ro_block_group_free_space( | ||
8065 | &sinfo->block_groups[i]); | ||
8066 | |||
8067 | spin_unlock(&sinfo->lock); | ||
8068 | |||
8069 | return free_bytes; | ||
8070 | } | ||
8071 | |||
8015 | int btrfs_set_block_group_rw(struct btrfs_root *root, | 8072 | int btrfs_set_block_group_rw(struct btrfs_root *root, |
8016 | struct btrfs_block_group_cache *cache) | 8073 | struct btrfs_block_group_cache *cache) |
8017 | { | 8074 | { |
@@ -8092,7 +8149,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
8092 | mutex_lock(&root->fs_info->chunk_mutex); | 8149 | mutex_lock(&root->fs_info->chunk_mutex); |
8093 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { | 8150 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { |
8094 | u64 min_free = btrfs_block_group_used(&block_group->item); | 8151 | u64 min_free = btrfs_block_group_used(&block_group->item); |
8095 | u64 dev_offset, max_avail; | 8152 | u64 dev_offset; |
8096 | 8153 | ||
8097 | /* | 8154 | /* |
8098 | * check to make sure we can actually find a chunk with enough | 8155 | * check to make sure we can actually find a chunk with enough |
@@ -8100,7 +8157,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
8100 | */ | 8157 | */ |
8101 | if (device->total_bytes > device->bytes_used + min_free) { | 8158 | if (device->total_bytes > device->bytes_used + min_free) { |
8102 | ret = find_free_dev_extent(NULL, device, min_free, | 8159 | ret = find_free_dev_extent(NULL, device, min_free, |
8103 | &dev_offset, &max_avail); | 8160 | &dev_offset, NULL); |
8104 | if (!ret) | 8161 | if (!ret) |
8105 | break; | 8162 | break; |
8106 | ret = -1; | 8163 | ret = -1; |
@@ -8584,3 +8641,14 @@ out: | |||
8584 | btrfs_free_path(path); | 8641 | btrfs_free_path(path); |
8585 | return ret; | 8642 | return ret; |
8586 | } | 8643 | } |
8644 | |||
8645 | int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) | ||
8646 | { | ||
8647 | return unpin_extent_range(root, start, end); | ||
8648 | } | ||
8649 | |||
8650 | int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, | ||
8651 | u64 num_bytes) | ||
8652 | { | ||
8653 | return btrfs_discard_extent(root, bytenr, num_bytes); | ||
8654 | } | ||