diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ea607f907232..8b158ae2443b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1942,8 +1942,8 @@ prepend: | |||
1942 | * There is no free space in the found leaf. | 1942 | * There is no free space in the found leaf. |
1943 | * We're gonna add a new leaf in the tree. | 1943 | * We're gonna add a new leaf in the tree. |
1944 | */ | 1944 | */ |
1945 | if (flag & EXT4_GET_BLOCKS_PUNCH_OUT_EXT) | 1945 | if (flag & EXT4_GET_BLOCKS_METADATA_NOFAIL) |
1946 | flags = EXT4_MB_USE_ROOT_BLOCKS; | 1946 | flags = EXT4_MB_USE_RESERVED; |
1947 | err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext); | 1947 | err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext); |
1948 | if (err) | 1948 | if (err) |
1949 | goto cleanup; | 1949 | goto cleanup; |
@@ -2729,12 +2729,14 @@ again: | |||
2729 | 2729 | ||
2730 | /* | 2730 | /* |
2731 | * Split the extent in two so that 'end' is the last | 2731 | * Split the extent in two so that 'end' is the last |
2732 | * block in the first new extent | 2732 | * block in the first new extent. Also we should not |
2733 | * fail removing space due to ENOSPC so try to use | ||
2734 | * reserved block if that happens. | ||
2733 | */ | 2735 | */ |
2734 | err = ext4_split_extent_at(handle, inode, path, | 2736 | err = ext4_split_extent_at(handle, inode, path, |
2735 | end + 1, split_flag, | 2737 | end + 1, split_flag, |
2736 | EXT4_GET_BLOCKS_PRE_IO | | 2738 | EXT4_GET_BLOCKS_PRE_IO | |
2737 | EXT4_GET_BLOCKS_PUNCH_OUT_EXT); | 2739 | EXT4_GET_BLOCKS_METADATA_NOFAIL); |
2738 | 2740 | ||
2739 | if (err < 0) | 2741 | if (err < 0) |
2740 | goto out; | 2742 | goto out; |
@@ -3209,7 +3211,8 @@ out: | |||
3209 | static int ext4_ext_convert_to_initialized(handle_t *handle, | 3211 | static int ext4_ext_convert_to_initialized(handle_t *handle, |
3210 | struct inode *inode, | 3212 | struct inode *inode, |
3211 | struct ext4_map_blocks *map, | 3213 | struct ext4_map_blocks *map, |
3212 | struct ext4_ext_path *path) | 3214 | struct ext4_ext_path *path, |
3215 | int flags) | ||
3213 | { | 3216 | { |
3214 | struct ext4_sb_info *sbi; | 3217 | struct ext4_sb_info *sbi; |
3215 | struct ext4_extent_header *eh; | 3218 | struct ext4_extent_header *eh; |
@@ -3435,7 +3438,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3435 | } | 3438 | } |
3436 | 3439 | ||
3437 | allocated = ext4_split_extent(handle, inode, path, | 3440 | allocated = ext4_split_extent(handle, inode, path, |
3438 | &split_map, split_flag, 0); | 3441 | &split_map, split_flag, flags); |
3439 | if (allocated < 0) | 3442 | if (allocated < 0) |
3440 | err = allocated; | 3443 | err = allocated; |
3441 | 3444 | ||
@@ -3755,6 +3758,12 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
3755 | flags, allocated); | 3758 | flags, allocated); |
3756 | ext4_ext_show_leaf(inode, path); | 3759 | ext4_ext_show_leaf(inode, path); |
3757 | 3760 | ||
3761 | /* | ||
3762 | * When writing into uninitialized space, we should not fail to | ||
3763 | * allocate metadata blocks for the new extent block if needed. | ||
3764 | */ | ||
3765 | flags |= EXT4_GET_BLOCKS_METADATA_NOFAIL; | ||
3766 | |||
3758 | trace_ext4_ext_handle_uninitialized_extents(inode, map, flags, | 3767 | trace_ext4_ext_handle_uninitialized_extents(inode, map, flags, |
3759 | allocated, newblock); | 3768 | allocated, newblock); |
3760 | 3769 | ||
@@ -3818,7 +3827,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
3818 | } | 3827 | } |
3819 | 3828 | ||
3820 | /* buffered write, writepage time, convert*/ | 3829 | /* buffered write, writepage time, convert*/ |
3821 | ret = ext4_ext_convert_to_initialized(handle, inode, map, path); | 3830 | ret = ext4_ext_convert_to_initialized(handle, inode, map, path, flags); |
3822 | if (ret >= 0) | 3831 | if (ret >= 0) |
3823 | ext4_update_inode_fsync_trans(handle, inode, 1); | 3832 | ext4_update_inode_fsync_trans(handle, inode, 1); |
3824 | out: | 3833 | out: |