diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 559f72489b3b..9e23ffea7f54 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/sort.h> | 22 | #include <linux/sort.h> |
| 23 | #include <linux/rcupdate.h> | 23 | #include <linux/rcupdate.h> |
| 24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
| 25 | #include <linux/slab.h> | ||
| 25 | #include "compat.h" | 26 | #include "compat.h" |
| 26 | #include "hash.h" | 27 | #include "hash.h" |
| 27 | #include "ctree.h" | 28 | #include "ctree.h" |
| @@ -2676,6 +2677,8 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
| 2676 | 2677 | ||
| 2677 | INIT_LIST_HEAD(&found->block_groups); | 2678 | INIT_LIST_HEAD(&found->block_groups); |
| 2678 | init_rwsem(&found->groups_sem); | 2679 | init_rwsem(&found->groups_sem); |
| 2680 | init_waitqueue_head(&found->flush_wait); | ||
| 2681 | init_waitqueue_head(&found->allocate_wait); | ||
| 2679 | spin_lock_init(&found->lock); | 2682 | spin_lock_init(&found->lock); |
| 2680 | found->flags = flags; | 2683 | found->flags = flags; |
| 2681 | found->total_bytes = total_bytes; | 2684 | found->total_bytes = total_bytes; |
| @@ -2846,7 +2849,7 @@ int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root, | |||
| 2846 | } | 2849 | } |
| 2847 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 2850 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
| 2848 | 2851 | ||
| 2849 | BTRFS_I(inode)->reserved_extents--; | 2852 | BTRFS_I(inode)->reserved_extents -= num_items; |
| 2850 | BUG_ON(BTRFS_I(inode)->reserved_extents < 0); | 2853 | BUG_ON(BTRFS_I(inode)->reserved_extents < 0); |
| 2851 | 2854 | ||
| 2852 | if (meta_sinfo->bytes_delalloc < num_bytes) { | 2855 | if (meta_sinfo->bytes_delalloc < num_bytes) { |
| @@ -2944,12 +2947,10 @@ static void flush_delalloc(struct btrfs_root *root, | |||
| 2944 | 2947 | ||
| 2945 | spin_lock(&info->lock); | 2948 | spin_lock(&info->lock); |
| 2946 | 2949 | ||
| 2947 | if (!info->flushing) { | 2950 | if (!info->flushing) |
| 2948 | info->flushing = 1; | 2951 | info->flushing = 1; |
| 2949 | init_waitqueue_head(&info->flush_wait); | 2952 | else |
| 2950 | } else { | ||
| 2951 | wait = true; | 2953 | wait = true; |
| 2952 | } | ||
| 2953 | 2954 | ||
| 2954 | spin_unlock(&info->lock); | 2955 | spin_unlock(&info->lock); |
| 2955 | 2956 | ||
| @@ -3011,7 +3012,6 @@ static int maybe_allocate_chunk(struct btrfs_root *root, | |||
| 3011 | if (!info->allocating_chunk) { | 3012 | if (!info->allocating_chunk) { |
| 3012 | info->force_alloc = 1; | 3013 | info->force_alloc = 1; |
| 3013 | info->allocating_chunk = 1; | 3014 | info->allocating_chunk = 1; |
| 3014 | init_waitqueue_head(&info->allocate_wait); | ||
| 3015 | } else { | 3015 | } else { |
| 3016 | wait = true; | 3016 | wait = true; |
| 3017 | } | 3017 | } |
| @@ -3111,7 +3111,7 @@ again: | |||
| 3111 | return -ENOSPC; | 3111 | return -ENOSPC; |
| 3112 | } | 3112 | } |
| 3113 | 3113 | ||
| 3114 | BTRFS_I(inode)->reserved_extents++; | 3114 | BTRFS_I(inode)->reserved_extents += num_items; |
| 3115 | check_force_delalloc(meta_sinfo); | 3115 | check_force_delalloc(meta_sinfo); |
| 3116 | spin_unlock(&meta_sinfo->lock); | 3116 | spin_unlock(&meta_sinfo->lock); |
| 3117 | 3117 | ||
| @@ -4170,6 +4170,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
| 4170 | ins->offset = 0; | 4170 | ins->offset = 0; |
| 4171 | 4171 | ||
| 4172 | space_info = __find_space_info(root->fs_info, data); | 4172 | space_info = __find_space_info(root->fs_info, data); |
| 4173 | if (!space_info) { | ||
| 4174 | printk(KERN_ERR "No space info for %d\n", data); | ||
| 4175 | return -ENOSPC; | ||
| 4176 | } | ||
| 4173 | 4177 | ||
| 4174 | if (orig_root->ref_cows || empty_size) | 4178 | if (orig_root->ref_cows || empty_size) |
| 4175 | allowed_chunk_alloc = 1; | 4179 | allowed_chunk_alloc = 1; |
| @@ -5205,6 +5209,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
| 5205 | next = btrfs_find_tree_block(root, bytenr, blocksize); | 5209 | next = btrfs_find_tree_block(root, bytenr, blocksize); |
| 5206 | if (!next) { | 5210 | if (!next) { |
| 5207 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); | 5211 | next = btrfs_find_create_tree_block(root, bytenr, blocksize); |
| 5212 | if (!next) | ||
| 5213 | return -ENOMEM; | ||
| 5208 | reada = 1; | 5214 | reada = 1; |
| 5209 | } | 5215 | } |
| 5210 | btrfs_tree_lock(next); | 5216 | btrfs_tree_lock(next); |
| @@ -5417,7 +5423,8 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
| 5417 | if (ret > 0) { | 5423 | if (ret > 0) { |
| 5418 | path->slots[level]++; | 5424 | path->slots[level]++; |
| 5419 | continue; | 5425 | continue; |
| 5420 | } | 5426 | } else if (ret < 0) |
| 5427 | return ret; | ||
| 5421 | level = wc->level; | 5428 | level = wc->level; |
| 5422 | } | 5429 | } |
| 5423 | return 0; | 5430 | return 0; |
| @@ -6561,6 +6568,7 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root, | |||
| 6561 | struct btrfs_key key; | 6568 | struct btrfs_key key; |
| 6562 | struct inode *inode = NULL; | 6569 | struct inode *inode = NULL; |
| 6563 | struct btrfs_file_extent_item *fi; | 6570 | struct btrfs_file_extent_item *fi; |
| 6571 | struct extent_state *cached_state = NULL; | ||
| 6564 | u64 num_bytes; | 6572 | u64 num_bytes; |
| 6565 | u64 skip_objectid = 0; | 6573 | u64 skip_objectid = 0; |
| 6566 | u32 nritems; | 6574 | u32 nritems; |
| @@ -6589,12 +6597,14 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root, | |||
| 6589 | } | 6597 | } |
| 6590 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); | 6598 | num_bytes = btrfs_file_extent_num_bytes(leaf, fi); |
| 6591 | 6599 | ||
| 6592 | lock_extent(&BTRFS_I(inode)->io_tree, key.offset, | 6600 | lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset, |
| 6593 | key.offset + num_bytes - 1, GFP_NOFS); | 6601 | key.offset + num_bytes - 1, 0, &cached_state, |
| 6602 | GFP_NOFS); | ||
| 6594 | btrfs_drop_extent_cache(inode, key.offset, | 6603 | btrfs_drop_extent_cache(inode, key.offset, |
| 6595 | key.offset + num_bytes - 1, 1); | 6604 | key.offset + num_bytes - 1, 1); |
| 6596 | unlock_extent(&BTRFS_I(inode)->io_tree, key.offset, | 6605 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset, |
| 6597 | key.offset + num_bytes - 1, GFP_NOFS); | 6606 | key.offset + num_bytes - 1, &cached_state, |
| 6607 | GFP_NOFS); | ||
| 6598 | cond_resched(); | 6608 | cond_resched(); |
| 6599 | } | 6609 | } |
| 6600 | iput(inode); | 6610 | iput(inode); |
| @@ -7366,7 +7376,6 @@ static int find_first_block_group(struct btrfs_root *root, | |||
| 7366 | } | 7376 | } |
| 7367 | path->slots[0]++; | 7377 | path->slots[0]++; |
| 7368 | } | 7378 | } |
| 7369 | ret = -ENOENT; | ||
| 7370 | out: | 7379 | out: |
| 7371 | return ret; | 7380 | return ret; |
| 7372 | } | 7381 | } |
