aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 2f82fabd7011..3d1be0b77f8f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2823,14 +2823,17 @@ int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
2823 num_items); 2823 num_items);
2824 2824
2825 spin_lock(&meta_sinfo->lock); 2825 spin_lock(&meta_sinfo->lock);
2826 if (BTRFS_I(inode)->delalloc_reserved_extents <= 2826 spin_lock(&BTRFS_I(inode)->accounting_lock);
2827 BTRFS_I(inode)->delalloc_extents) { 2827 if (BTRFS_I(inode)->reserved_extents <=
2828 BTRFS_I(inode)->outstanding_extents) {
2829 spin_unlock(&BTRFS_I(inode)->accounting_lock);
2828 spin_unlock(&meta_sinfo->lock); 2830 spin_unlock(&meta_sinfo->lock);
2829 return 0; 2831 return 0;
2830 } 2832 }
2833 spin_unlock(&BTRFS_I(inode)->accounting_lock);
2831 2834
2832 BTRFS_I(inode)->delalloc_reserved_extents--; 2835 BTRFS_I(inode)->reserved_extents--;
2833 BUG_ON(BTRFS_I(inode)->delalloc_reserved_extents < 0); 2836 BUG_ON(BTRFS_I(inode)->reserved_extents < 0);
2834 2837
2835 if (meta_sinfo->bytes_delalloc < num_bytes) { 2838 if (meta_sinfo->bytes_delalloc < num_bytes) {
2836 bug = true; 2839 bug = true;
@@ -2863,6 +2866,37 @@ static void check_force_delalloc(struct btrfs_space_info *meta_sinfo)
2863 meta_sinfo->force_delalloc = 0; 2866 meta_sinfo->force_delalloc = 0;
2864} 2867}
2865 2868
2869static void flush_delalloc(struct btrfs_root *root,
2870 struct btrfs_space_info *info)
2871{
2872 bool wait = false;
2873
2874 spin_lock(&info->lock);
2875
2876 if (!info->flushing) {
2877 info->flushing = 1;
2878 init_waitqueue_head(&info->flush_wait);
2879 } else {
2880 wait = true;
2881 }
2882
2883 spin_unlock(&info->lock);
2884
2885 if (wait) {
2886 wait_event(info->flush_wait,
2887 !info->flushing);
2888 return;
2889 }
2890
2891 btrfs_start_delalloc_inodes(root);
2892 btrfs_wait_ordered_extents(root, 0);
2893
2894 spin_lock(&info->lock);
2895 info->flushing = 0;
2896 spin_unlock(&info->lock);
2897 wake_up(&info->flush_wait);
2898}
2899
2866static int maybe_allocate_chunk(struct btrfs_root *root, 2900static int maybe_allocate_chunk(struct btrfs_root *root,
2867 struct btrfs_space_info *info) 2901 struct btrfs_space_info *info)
2868{ 2902{
@@ -2980,21 +3014,20 @@ again:
2980 filemap_flush(inode->i_mapping); 3014 filemap_flush(inode->i_mapping);
2981 goto again; 3015 goto again;
2982 } else if (flushed == 3) { 3016 } else if (flushed == 3) {
2983 btrfs_start_delalloc_inodes(root); 3017 flush_delalloc(root, meta_sinfo);
2984 btrfs_wait_ordered_extents(root, 0);
2985 goto again; 3018 goto again;
2986 } 3019 }
2987 spin_lock(&meta_sinfo->lock); 3020 spin_lock(&meta_sinfo->lock);
2988 meta_sinfo->bytes_delalloc -= num_bytes; 3021 meta_sinfo->bytes_delalloc -= num_bytes;
2989 spin_unlock(&meta_sinfo->lock); 3022 spin_unlock(&meta_sinfo->lock);
2990 printk(KERN_ERR "enospc, has %d, reserved %d\n", 3023 printk(KERN_ERR "enospc, has %d, reserved %d\n",
2991 BTRFS_I(inode)->delalloc_extents, 3024 BTRFS_I(inode)->outstanding_extents,
2992 BTRFS_I(inode)->delalloc_reserved_extents); 3025 BTRFS_I(inode)->reserved_extents);
2993 dump_space_info(meta_sinfo, 0, 0); 3026 dump_space_info(meta_sinfo, 0, 0);
2994 return -ENOSPC; 3027 return -ENOSPC;
2995 } 3028 }
2996 3029
2997 BTRFS_I(inode)->delalloc_reserved_extents++; 3030 BTRFS_I(inode)->reserved_extents++;
2998 check_force_delalloc(meta_sinfo); 3031 check_force_delalloc(meta_sinfo);
2999 spin_unlock(&meta_sinfo->lock); 3032 spin_unlock(&meta_sinfo->lock);
3000 3033
@@ -3093,8 +3126,7 @@ again:
3093 } 3126 }
3094 3127
3095 if (retries == 2) { 3128 if (retries == 2) {
3096 btrfs_start_delalloc_inodes(root); 3129 flush_delalloc(root, meta_sinfo);
3097 btrfs_wait_ordered_extents(root, 0);
3098 goto again; 3130 goto again;
3099 } 3131 }
3100 spin_lock(&meta_sinfo->lock); 3132 spin_lock(&meta_sinfo->lock);