diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 13 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 143 | ||||
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 33 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 41 |
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); |
| 3317 | int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, | 3325 | int 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); |
| 3320 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3328 | int 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); |
| 3322 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3330 | int 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 | ||
| 3333 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); | 3341 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len, |
| 3342 | int delalloc); | ||
| 3334 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, | 3343 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, |
| 3335 | u64 start, u64 len); | 3344 | u64 start, u64 len); |
| 3336 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | 3345 | void 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, | |||
| 105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, | 105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, |
| 106 | int dump_block_groups); | 106 | int dump_block_groups); |
| 107 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 107 | static 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); | ||
| 109 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, | 110 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, |
| 110 | u64 num_bytes); | 111 | u64 num_bytes); |
| 111 | int btrfs_pin_extent(struct btrfs_root *root, | 112 | int 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 | */ |
| 5633 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 5636 | static 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 | ||
| 6377 | static inline void | ||
| 6378 | btrfs_lock_block_group(struct btrfs_block_group_cache *cache, | ||
| 6379 | int delalloc) | ||
| 6380 | { | ||
| 6381 | if (delalloc) | ||
| 6382 | down_read(&cache->data_rwsem); | ||
| 6383 | } | ||
| 6384 | |||
| 6385 | static inline void | ||
| 6386 | btrfs_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 | |||
| 6394 | static struct btrfs_block_group_cache * | ||
| 6395 | btrfs_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; | ||
| 6401 | again: | ||
| 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 | } | ||
