diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 7d54850f7136..a2c21aa09e2b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3186,7 +3186,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
3186 | { | 3186 | { |
3187 | struct ext4_ext_path *path = NULL; | 3187 | struct ext4_ext_path *path = NULL; |
3188 | struct ext4_extent_header *eh; | 3188 | struct ext4_extent_header *eh; |
3189 | struct ext4_extent newex, *ex; | 3189 | struct ext4_extent newex, *ex, *last_ex; |
3190 | ext4_fsblk_t newblock; | 3190 | ext4_fsblk_t newblock; |
3191 | int err = 0, depth, ret, cache_type; | 3191 | int err = 0, depth, ret, cache_type; |
3192 | unsigned int allocated = 0; | 3192 | unsigned int allocated = 0; |
@@ -3367,6 +3367,19 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
3367 | EXT4_STATE_DIO_UNWRITTEN); | 3367 | EXT4_STATE_DIO_UNWRITTEN); |
3368 | } | 3368 | } |
3369 | } | 3369 | } |
3370 | |||
3371 | if (unlikely(EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL)) { | ||
3372 | if (eh->eh_entries) { | ||
3373 | last_ex = EXT_LAST_EXTENT(eh); | ||
3374 | if (iblock + ar.len > le32_to_cpu(last_ex->ee_block) | ||
3375 | + ext4_ext_get_actual_len(last_ex)) | ||
3376 | EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL; | ||
3377 | } else { | ||
3378 | WARN_ON(eh->eh_entries == 0); | ||
3379 | ext4_error(inode->i_sb, __func__, | ||
3380 | "inode#%lu, eh->eh_entries = 0!", inode->i_ino); | ||
3381 | } | ||
3382 | } | ||
3370 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); | 3383 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); |
3371 | if (err) { | 3384 | if (err) { |
3372 | /* free data blocks we just allocated */ | 3385 | /* free data blocks we just allocated */ |
@@ -3500,6 +3513,13 @@ static void ext4_falloc_update_inode(struct inode *inode, | |||
3500 | i_size_write(inode, new_size); | 3513 | i_size_write(inode, new_size); |
3501 | if (new_size > EXT4_I(inode)->i_disksize) | 3514 | if (new_size > EXT4_I(inode)->i_disksize) |
3502 | ext4_update_i_disksize(inode, new_size); | 3515 | ext4_update_i_disksize(inode, new_size); |
3516 | } else { | ||
3517 | /* | ||
3518 | * Mark that we allocate beyond EOF so the subsequent truncate | ||
3519 | * can proceed even if the new size is the same as i_size. | ||
3520 | */ | ||
3521 | if (new_size > i_size_read(inode)) | ||
3522 | EXT4_I(inode)->i_flags |= EXT4_EOFBLOCKS_FL; | ||
3503 | } | 3523 | } |
3504 | 3524 | ||
3505 | } | 3525 | } |