aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h13
-rw-r--r--fs/btrfs/extent-tree.c143
-rw-r--r--fs/btrfs/free-space-cache.c33
-rw-r--r--fs/btrfs/inode.c41
4 files changed, 186 insertions, 44 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b7e2c1c1ef36..be91397f4e92 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1259,11 +1259,19 @@ struct btrfs_block_group_cache {
1259 spinlock_t lock; 1259 spinlock_t lock;
1260 u64 pinned; 1260 u64 pinned;
1261 u64 reserved; 1261 u64 reserved;
1262 u64 delalloc_bytes;
1262 u64 bytes_super; 1263 u64 bytes_super;
1263 u64 flags; 1264 u64 flags;
1264 u64 sectorsize; 1265 u64 sectorsize;
1265 u64 cache_generation; 1266 u64 cache_generation;
1266 1267
1268 /*
1269 * It is just used for the delayed data space allocation because
1270 * only the data space allocation and the relative metadata update
1271 * can be done cross the transaction.
1272 */
1273 struct rw_semaphore data_rwsem;
1274
1267 /* for raid56, this is a full stripe, without parity */ 1275 /* for raid56, this is a full stripe, without parity */
1268 unsigned long full_stripe_len; 1276 unsigned long full_stripe_len;
1269 1277
@@ -3316,7 +3324,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
3316 struct btrfs_key *ins); 3324 struct btrfs_key *ins);
3317int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, 3325int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes,
3318 u64 min_alloc_size, u64 empty_size, u64 hint_byte, 3326 u64 min_alloc_size, u64 empty_size, u64 hint_byte,
3319 struct btrfs_key *ins, int is_data); 3327 struct btrfs_key *ins, int is_data, int delalloc);
3320int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 3328int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
3321 struct extent_buffer *buf, int full_backref, int no_quota); 3329 struct extent_buffer *buf, int full_backref, int no_quota);
3322int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 3330int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
@@ -3330,7 +3338,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
3330 u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, 3338 u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
3331 u64 owner, u64 offset, int no_quota); 3339 u64 owner, u64 offset, int no_quota);
3332 3340
3333int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); 3341int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len,
3342 int delalloc);
3334int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, 3343int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root,
3335 u64 start, u64 len); 3344 u64 start, u64 len);
3336void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, 3345void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fafb3e53ecde..99c253918208 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -105,7 +105,8 @@ static int find_next_key(struct btrfs_path *path, int level,
105static void dump_space_info(struct btrfs_space_info *info, u64 bytes, 105static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
106 int dump_block_groups); 106 int dump_block_groups);
107static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, 107static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
108 u64 num_bytes, int reserve); 108 u64 num_bytes, int reserve,
109 int delalloc);
109static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, 110static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv,
110 u64 num_bytes); 111 u64 num_bytes);
111int btrfs_pin_extent(struct btrfs_root *root, 112int btrfs_pin_extent(struct btrfs_root *root,
@@ -3260,7 +3261,8 @@ again:
3260 3261
3261 spin_lock(&block_group->lock); 3262 spin_lock(&block_group->lock);
3262 if (block_group->cached != BTRFS_CACHE_FINISHED || 3263 if (block_group->cached != BTRFS_CACHE_FINISHED ||
3263 !btrfs_test_opt(root, SPACE_CACHE)) { 3264 !btrfs_test_opt(root, SPACE_CACHE) ||
3265 block_group->delalloc_bytes) {
3264 /* 3266 /*
3265 * don't bother trying to write stuff out _if_ 3267 * don't bother trying to write stuff out _if_
3266 * a) we're not cached, 3268 * a) we're not cached,
@@ -5613,6 +5615,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log,
5613 * @cache: The cache we are manipulating 5615 * @cache: The cache we are manipulating
5614 * @num_bytes: The number of bytes in question 5616 * @num_bytes: The number of bytes in question
5615 * @reserve: One of the reservation enums 5617 * @reserve: One of the reservation enums
5618 * @delalloc: The blocks are allocated for the delalloc write
5616 * 5619 *
5617 * This is called by the allocator when it reserves space, or by somebody who is 5620 * This is called by the allocator when it reserves space, or by somebody who is
5618 * freeing space that was never actually used on disk. For example if you 5621 * freeing space that was never actually used on disk. For example if you
@@ -5631,7 +5634,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log,
5631 * succeeds. 5634 * succeeds.
5632 */ 5635 */
5633static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, 5636static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
5634 u64 num_bytes, int reserve) 5637 u64 num_bytes, int reserve, int delalloc)
5635{ 5638{
5636 struct btrfs_space_info *space_info = cache->space_info; 5639 struct btrfs_space_info *space_info = cache->space_info;
5637 int ret = 0; 5640 int ret = 0;
@@ -5650,12 +5653,18 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
5650 num_bytes, 0); 5653 num_bytes, 0);
5651 space_info->bytes_may_use -= num_bytes; 5654 space_info->bytes_may_use -= num_bytes;
5652 } 5655 }
5656
5657 if (delalloc)
5658 cache->delalloc_bytes += num_bytes;
5653 } 5659 }
5654 } else { 5660 } else {
5655 if (cache->ro) 5661 if (cache->ro)
5656 space_info->bytes_readonly += num_bytes; 5662 space_info->bytes_readonly += num_bytes;
5657 cache->reserved -= num_bytes; 5663 cache->reserved -= num_bytes;
5658 space_info->bytes_reserved -= num_bytes; 5664 space_info->bytes_reserved -= num_bytes;
5665
5666 if (delalloc)
5667 cache->delalloc_bytes -= num_bytes;
5659 } 5668 }
5660 spin_unlock(&cache->lock); 5669 spin_unlock(&cache->lock);
5661 spin_unlock(&space_info->lock); 5670 spin_unlock(&space_info->lock);
@@ -6206,7 +6215,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
6206 WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); 6215 WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags));
6207 6216
6208 btrfs_add_free_space(cache, buf->start, buf->len); 6217 btrfs_add_free_space(cache, buf->start, buf->len);
6209 btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE); 6218 btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE, 0);
6210 trace_btrfs_reserved_extent_free(root, buf->start, buf->len); 6219 trace_btrfs_reserved_extent_free(root, buf->start, buf->len);
6211 pin = 0; 6220 pin = 0;
6212 } 6221 }
@@ -6365,6 +6374,70 @@ enum btrfs_loop_type {
6365 LOOP_NO_EMPTY_SIZE = 3, 6374 LOOP_NO_EMPTY_SIZE = 3,
6366}; 6375};
6367 6376
6377static inline void
6378btrfs_lock_block_group(struct btrfs_block_group_cache *cache,
6379 int delalloc)
6380{
6381 if (delalloc)
6382 down_read(&cache->data_rwsem);
6383}
6384
6385static inline void
6386btrfs_grab_block_group(struct btrfs_block_group_cache *cache,
6387 int delalloc)
6388{
6389 btrfs_get_block_group(cache);
6390 if (delalloc)
6391 down_read(&cache->data_rwsem);
6392}
6393
6394static struct btrfs_block_group_cache *
6395btrfs_lock_cluster(struct btrfs_block_group_cache *block_group,
6396 struct btrfs_free_cluster *cluster,
6397 int delalloc)
6398{
6399 struct btrfs_block_group_cache *used_bg;
6400 bool locked = false;
6401again:
6402 spin_lock(&cluster->refill_lock);
6403 if (locked) {
6404 if (used_bg == cluster->block_group)
6405 return used_bg;
6406
6407 up_read(&used_bg->data_rwsem);
6408 btrfs_put_block_group(used_bg);
6409 }
6410
6411 used_bg = cluster->block_group;
6412 if (!used_bg)
6413 return NULL;
6414
6415 if (used_bg == block_group)
6416 return used_bg;
6417
6418 btrfs_get_block_group(used_bg);
6419
6420 if (!delalloc)
6421 return used_bg;
6422
6423 if (down_read_trylock(&used_bg->data_rwsem))
6424 return used_bg;
6425
6426 spin_unlock(&cluster->refill_lock);
6427 down_read(&used_bg->data_rwsem);
6428 locked = true;
6429 goto again;
6430}