aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c22
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}