diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 54 |
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 | ||
2869 | static 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 | |||
2866 | static int maybe_allocate_chunk(struct btrfs_root *root, | 2900 | static 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); |