diff options
| author | Takashi Iwai <tiwai@suse.de> | 2009-12-25 08:15:31 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2009-12-25 08:15:31 -0500 |
| commit | 52e04ea89da57274f0313d2bd73ba02f686cfdeb (patch) | |
| tree | 6ce5d086bcaea4cb534b3fcf6ba736eb48d582a4 /fs/btrfs/extent-tree.c | |
| parent | 41116e926cb92292fa4fcbe888ae8133fa0038e6 (diff) | |
| parent | 8b90ca08821fee79e181bfcbc3bbd41ef5637136 (diff) | |
Merge branch 'fix/misc' into topic/misc
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 94627c4cc193..56e50137d0e6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -195,6 +195,14 @@ static int exclude_super_stripes(struct btrfs_root *root, | |||
| 195 | int stripe_len; | 195 | int stripe_len; |
| 196 | int i, nr, ret; | 196 | int i, nr, ret; |
| 197 | 197 | ||
| 198 | if (cache->key.objectid < BTRFS_SUPER_INFO_OFFSET) { | ||
| 199 | stripe_len = BTRFS_SUPER_INFO_OFFSET - cache->key.objectid; | ||
| 200 | cache->bytes_super += stripe_len; | ||
| 201 | ret = add_excluded_extent(root, cache->key.objectid, | ||
| 202 | stripe_len); | ||
| 203 | BUG_ON(ret); | ||
| 204 | } | ||
| 205 | |||
| 198 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { | 206 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { |
| 199 | bytenr = btrfs_sb_offset(i); | 207 | bytenr = btrfs_sb_offset(i); |
| 200 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, | 208 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, |
| @@ -255,7 +263,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, | |||
| 255 | if (ret) | 263 | if (ret) |
| 256 | break; | 264 | break; |
| 257 | 265 | ||
| 258 | if (extent_start == start) { | 266 | if (extent_start <= start) { |
| 259 | start = extent_end + 1; | 267 | start = extent_end + 1; |
| 260 | } else if (extent_start > start && extent_start < end) { | 268 | } else if (extent_start > start && extent_start < end) { |
| 261 | size = extent_start - start; | 269 | size = extent_start - start; |
| @@ -2880,9 +2888,9 @@ static noinline void flush_delalloc_async(struct btrfs_work *work) | |||
| 2880 | root = async->root; | 2888 | root = async->root; |
| 2881 | info = async->info; | 2889 | info = async->info; |
| 2882 | 2890 | ||
| 2883 | btrfs_start_delalloc_inodes(root); | 2891 | btrfs_start_delalloc_inodes(root, 0); |
| 2884 | wake_up(&info->flush_wait); | 2892 | wake_up(&info->flush_wait); |
| 2885 | btrfs_wait_ordered_extents(root, 0); | 2893 | btrfs_wait_ordered_extents(root, 0, 0); |
| 2886 | 2894 | ||
| 2887 | spin_lock(&info->lock); | 2895 | spin_lock(&info->lock); |
| 2888 | info->flushing = 0; | 2896 | info->flushing = 0; |
| @@ -2956,8 +2964,8 @@ static void flush_delalloc(struct btrfs_root *root, | |||
| 2956 | return; | 2964 | return; |
| 2957 | 2965 | ||
| 2958 | flush: | 2966 | flush: |
| 2959 | btrfs_start_delalloc_inodes(root); | 2967 | btrfs_start_delalloc_inodes(root, 0); |
| 2960 | btrfs_wait_ordered_extents(root, 0); | 2968 | btrfs_wait_ordered_extents(root, 0, 0); |
| 2961 | 2969 | ||
| 2962 | spin_lock(&info->lock); | 2970 | spin_lock(&info->lock); |
| 2963 | info->flushing = 0; | 2971 | info->flushing = 0; |
| @@ -3454,14 +3462,6 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
| 3454 | else | 3462 | else |
| 3455 | old_val -= num_bytes; | 3463 | old_val -= num_bytes; |
| 3456 | btrfs_set_super_bytes_used(&info->super_copy, old_val); | 3464 | btrfs_set_super_bytes_used(&info->super_copy, old_val); |
| 3457 | |||
| 3458 | /* block accounting for root item */ | ||
| 3459 | old_val = btrfs_root_used(&root->root_item); | ||
| 3460 | if (alloc) | ||
| 3461 | old_val += num_bytes; | ||
| 3462 | else | ||
| 3463 | old_val -= num_bytes; | ||
| 3464 | btrfs_set_root_used(&root->root_item, old_val); | ||
| 3465 | spin_unlock(&info->delalloc_lock); | 3465 | spin_unlock(&info->delalloc_lock); |
| 3466 | 3466 | ||
| 3467 | while (total) { | 3467 | while (total) { |
| @@ -4049,6 +4049,21 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
| 4049 | return ret; | 4049 | return ret; |
| 4050 | } | 4050 | } |
| 4051 | 4051 | ||
| 4052 | int btrfs_free_tree_block(struct btrfs_trans_handle *trans, | ||
| 4053 | struct btrfs_root *root, | ||
| 4054 | u64 bytenr, u32 blocksize, | ||
| 4055 | u64 parent, u64 root_objectid, int level) | ||
| 4056 | { | ||
| 4057 | u64 used; | ||
| 4058 | spin_lock(&root->node_lock); | ||
| 4059 | used = btrfs_root_used(&root->root_item) - blocksize; | ||
| 4060 | btrfs_set_root_used(&root->root_item, used); | ||
| 4061 | spin_unlock(&root->node_lock); | ||
| 4062 | |||
| 4063 | return btrfs_free_extent(trans, root, bytenr, blocksize, | ||
| 4064 | parent, root_objectid, level, 0); | ||
| 4065 | } | ||
| 4066 | |||
| 4052 | static u64 stripe_align(struct btrfs_root *root, u64 val) | 4067 | static u64 stripe_align(struct btrfs_root *root, u64 val) |
| 4053 | { | 4068 | { |
| 4054 | u64 mask = ((u64)root->stripesize - 1); | 4069 | u64 mask = ((u64)root->stripesize - 1); |
| @@ -4578,7 +4593,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
| 4578 | { | 4593 | { |
| 4579 | int ret; | 4594 | int ret; |
| 4580 | u64 search_start = 0; | 4595 | u64 search_start = 0; |
| 4581 | struct btrfs_fs_info *info = root->fs_info; | ||
| 4582 | 4596 | ||
| 4583 | data = btrfs_get_alloc_profile(root, data); | 4597 | data = btrfs_get_alloc_profile(root, data); |
| 4584 | again: | 4598 | again: |
| @@ -4586,17 +4600,9 @@ again: | |||
| 4586 | * the only place that sets empty_size is btrfs_realloc_node, which | 4600 | * the only place that sets empty_size is btrfs_realloc_node, which |
| 4587 | * is not called recursively on allocations | 4601 | * is not called recursively on allocations |
| 4588 | */ | 4602 | */ |
| 4589 | if (empty_size || root->ref_cows) { | 4603 | if (empty_size || root->ref_cows) |
| 4590 | if (!(data & BTRFS_BLOCK_GROUP_METADATA)) { | ||
| 4591 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
| 4592 | 2 * 1024 * 1024, | ||
| 4593 | BTRFS_BLOCK_GROUP_METADATA | | ||
| 4594 | (info->metadata_alloc_profile & | ||
| 4595 | info->avail_metadata_alloc_bits), 0); | ||
| 4596 | } | ||
| 4597 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | 4604 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, |
| 4598 | num_bytes + 2 * 1024 * 1024, data, 0); | 4605 | num_bytes + 2 * 1024 * 1024, data, 0); |
| 4599 | } | ||
| 4600 | 4606 | ||
| 4601 | WARN_ON(num_bytes < root->sectorsize); | 4607 | WARN_ON(num_bytes < root->sectorsize); |
| 4602 | ret = find_free_extent(trans, root, num_bytes, empty_size, | 4608 | ret = find_free_extent(trans, root, num_bytes, empty_size, |
| @@ -4897,6 +4903,14 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, | |||
| 4897 | extent_op); | 4903 | extent_op); |
| 4898 | BUG_ON(ret); | 4904 | BUG_ON(ret); |
| 4899 | } | 4905 | } |
| 4906 | |||
| 4907 | if (root_objectid == root->root_key.objectid) { | ||
| 4908 | u64 used; | ||
| 4909 | spin_lock(&root->node_lock); | ||
| 4910 | used = btrfs_root_used(&root->root_item) + num_bytes; | ||
| 4911 | btrfs_set_root_used(&root->root_item, used); | ||
| 4912 | spin_unlock(&root->node_lock); | ||
| 4913 | } | ||
| 4900 | return ret; | 4914 | return ret; |
| 4901 | } | 4915 | } |
| 4902 | 4916 | ||
| @@ -4919,8 +4933,16 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
| 4919 | btrfs_set_buffer_uptodate(buf); | 4933 | btrfs_set_buffer_uptodate(buf); |
| 4920 | 4934 | ||
| 4921 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { | 4935 | if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { |
| 4922 | set_extent_dirty(&root->dirty_log_pages, buf->start, | 4936 | /* |
| 4923 | buf->start + buf->len - 1, GFP_NOFS); | 4937 | * we allow two log transactions at a time, use different |
| 4938 | * EXENT bit to differentiate dirty pages. | ||
| 4939 | */ | ||
| 4940 | if (root->log_transid % 2 == 0) | ||
| 4941 | set_extent_dirty(&root->dirty_log_pages, buf->start, | ||
| 4942 | buf->start + buf->len - 1, GFP_NOFS); | ||
| 4943 | else | ||
| 4944 | set_extent_new(&root->dirty_log_pages, buf->start, | ||
| 4945 | buf->start + buf->len - 1, GFP_NOFS); | ||
| 4924 | } else { | 4946 | } else { |
| 4925 | set_extent_dirty(&trans->transaction->dirty_pages, buf->start, | 4947 | set_extent_dirty(&trans->transaction->dirty_pages, buf->start, |
| 4926 | buf->start + buf->len - 1, GFP_NOFS); | 4948 | buf->start + buf->len - 1, GFP_NOFS); |
