diff options
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r-- | fs/btrfs/file.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 5842423f8f47..fea31a4a6e36 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2070,7 +2070,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2070 | } | 2070 | } |
2071 | trans->sync = true; | 2071 | trans->sync = true; |
2072 | 2072 | ||
2073 | btrfs_init_log_ctx(&ctx); | 2073 | btrfs_init_log_ctx(&ctx, inode); |
2074 | 2074 | ||
2075 | ret = btrfs_log_dentry_safe(trans, root, dentry, start, end, &ctx); | 2075 | ret = btrfs_log_dentry_safe(trans, root, dentry, start, end, &ctx); |
2076 | if (ret < 0) { | 2076 | if (ret < 0) { |
@@ -2675,6 +2675,7 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2675 | 2675 | ||
2676 | alloc_start = round_down(offset, blocksize); | 2676 | alloc_start = round_down(offset, blocksize); |
2677 | alloc_end = round_up(offset + len, blocksize); | 2677 | alloc_end = round_up(offset + len, blocksize); |
2678 | cur_offset = alloc_start; | ||
2678 | 2679 | ||
2679 | /* Make sure we aren't being give some crap mode */ | 2680 | /* Make sure we aren't being give some crap mode */ |
2680 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) | 2681 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) |
@@ -2767,7 +2768,6 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2767 | 2768 | ||
2768 | /* First, check if we exceed the qgroup limit */ | 2769 | /* First, check if we exceed the qgroup limit */ |
2769 | INIT_LIST_HEAD(&reserve_list); | 2770 | INIT_LIST_HEAD(&reserve_list); |
2770 | cur_offset = alloc_start; | ||
2771 | while (1) { | 2771 | while (1) { |
2772 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, | 2772 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, |
2773 | alloc_end - cur_offset, 0); | 2773 | alloc_end - cur_offset, 0); |
@@ -2794,6 +2794,14 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2794 | last_byte - cur_offset); | 2794 | last_byte - cur_offset); |
2795 | if (ret < 0) | 2795 | if (ret < 0) |
2796 | break; | 2796 | break; |
2797 | } else { | ||
2798 | /* | ||
2799 | * Do not need to reserve unwritten extent for this | ||
2800 | * range, free reserved data space first, otherwise | ||
2801 | * it'll result in false ENOSPC error. | ||
2802 | */ | ||
2803 | btrfs_free_reserved_data_space(inode, cur_offset, | ||
2804 | last_byte - cur_offset); | ||
2797 | } | 2805 | } |
2798 | free_extent_map(em); | 2806 | free_extent_map(em); |
2799 | cur_offset = last_byte; | 2807 | cur_offset = last_byte; |
@@ -2811,6 +2819,9 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
2811 | range->start, | 2819 | range->start, |
2812 | range->len, 1 << inode->i_blkbits, | 2820 | range->len, 1 << inode->i_blkbits, |
2813 | offset + len, &alloc_hint); | 2821 | offset + len, &alloc_hint); |
2822 | else | ||
2823 | btrfs_free_reserved_data_space(inode, range->start, | ||
2824 | range->len); | ||
2814 | list_del(&range->list); | 2825 | list_del(&range->list); |
2815 | kfree(range); | 2826 | kfree(range); |
2816 | } | 2827 | } |
@@ -2845,18 +2856,11 @@ out_unlock: | |||
2845 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, | 2856 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, |
2846 | &cached_state, GFP_KERNEL); | 2857 | &cached_state, GFP_KERNEL); |
2847 | out: | 2858 | out: |
2848 | /* | ||
2849 | * As we waited the extent range, the data_rsv_map must be empty | ||
2850 | * in the range, as written data range will be released from it. | ||
2851 | * And for prealloacted extent, it will also be released when | ||
2852 | * its metadata is written. | ||
2853 | * So this is completely used as cleanup. | ||
2854 | */ | ||
2855 | btrfs_qgroup_free_data(inode, alloc_start, alloc_end - alloc_start); | ||
2856 | inode_unlock(inode); | 2859 | inode_unlock(inode); |
2857 | /* Let go of our reservation. */ | 2860 | /* Let go of our reservation. */ |
2858 | btrfs_free_reserved_data_space(inode, alloc_start, | 2861 | if (ret != 0) |
2859 | alloc_end - alloc_start); | 2862 | btrfs_free_reserved_data_space(inode, alloc_start, |
2863 | alloc_end - cur_offset); | ||
2860 | return ret; | 2864 | return ret; |
2861 | } | 2865 | } |
2862 | 2866 | ||