aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2011-10-25 08:15:12 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-10-25 08:15:12 -0400
commita4e5d88b1b24827f4f6a3cba43228936a67d81ba (patch)
tree0f5b0309f290f5fc23478794c6f4adcd7c18896a /fs/ext4/extents.c
parent750c9c47a5f9daa88333ac435a1afe4d4b428230 (diff)
ext4: update EOFBLOCKS flag on fallocate properly
EOFBLOCK_FL should be updated if called w/o FALLOCATE_FL_KEEP_SIZE Currently it happens only if new extent was allocated. TESTCASE: fallocate test_file -n -l4096 fallocate test_file -l4096 Last fallocate cmd has updated size, but keept EOFBLOCK_FL set. And fsck will complain about that. Also remove ping pong in ext4_fallocate() in case of new extents, where ext4_ext_map_blocks() clear EOFBLOCKS bit, and later ext4_falloc_update_inode() restore it again. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index d0e3f333d3f0..8686eb756b38 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3432,14 +3432,8 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
3432 3432
3433 /* buffered write, writepage time, convert*/ 3433 /* buffered write, writepage time, convert*/
3434 ret = ext4_ext_convert_to_initialized(handle, inode, map, path); 3434 ret = ext4_ext_convert_to_initialized(handle, inode, map, path);
3435 if (ret >= 0) { 3435 if (ret >= 0)
3436 ext4_update_inode_fsync_trans(handle, inode, 1); 3436 ext4_update_inode_fsync_trans(handle, inode, 1);
3437 err = check_eofblocks_fl(handle, inode, map->m_lblk, path,
3438 map->m_len);
3439 if (err < 0)
3440 goto out2;
3441 }
3442
3443out: 3437out:
3444 if (ret <= 0) { 3438 if (ret <= 0) {
3445 err = ret; 3439 err = ret;
@@ -3480,6 +3474,12 @@ out:
3480 3474
3481map_out: 3475map_out:
3482 map->m_flags |= EXT4_MAP_MAPPED; 3476 map->m_flags |= EXT4_MAP_MAPPED;
3477 if ((flags & EXT4_GET_BLOCKS_KEEP_SIZE) == 0) {
3478 err = check_eofblocks_fl(handle, inode, map->m_lblk, path,
3479 map->m_len);
3480 if (err < 0)
3481 goto out2;
3482 }
3483out1: 3483out1:
3484 if (allocated > map->m_len) 3484 if (allocated > map->m_len)
3485 allocated = map->m_len; 3485 allocated = map->m_len;
@@ -3955,7 +3955,10 @@ got_allocated_blocks:
3955 map->m_flags |= EXT4_MAP_UNINIT; 3955 map->m_flags |= EXT4_MAP_UNINIT;
3956 } 3956 }
3957 3957
3958 err = check_eofblocks_fl(handle, inode, map->m_lblk, path, ar.len); 3958 err = 0;
3959 if ((flags & EXT4_GET_BLOCKS_KEEP_SIZE) == 0)
3960 err = check_eofblocks_fl(handle, inode, map->m_lblk,
3961 path, ar.len);
3959 if (!err) 3962 if (!err)
3960 err = ext4_ext_insert_extent(handle, inode, path, 3963 err = ext4_ext_insert_extent(handle, inode, path,
3961 &newex, flags); 3964 &newex, flags);
@@ -4214,6 +4217,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
4214 int ret = 0; 4217 int ret = 0;
4215 int ret2 = 0; 4218 int ret2 = 0;
4216 int retries = 0; 4219 int retries = 0;
4220 int flags;
4217 struct ext4_map_blocks map; 4221 struct ext4_map_blocks map;
4218 unsigned int credits, blkbits = inode->i_blkbits; 4222 unsigned int credits, blkbits = inode->i_blkbits;
4219 4223
@@ -4250,6 +4254,10 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
4250 trace_ext4_fallocate_exit(inode, offset, max_blocks, ret); 4254 trace_ext4_fallocate_exit(inode, offset, max_blocks, ret);
4251 return ret; 4255 return ret;
4252 } 4256 }
4257 flags = EXT4_GET_BLOCKS_CREATE_UNINIT_EXT |
4258 EXT4_GET_BLOCKS_NO_NORMALIZE;
4259 if (mode & FALLOC_FL_KEEP_SIZE)
4260 flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
4253retry: 4261retry:
4254 while (ret >= 0 && ret < max_blocks) { 4262 while (ret >= 0 && ret < max_blocks) {
4255 map.m_lblk = map.m_lblk + ret; 4263 map.m_lblk = map.m_lblk + ret;
@@ -4259,9 +4267,7 @@ retry:
4259 ret = PTR_ERR(handle); 4267 ret = PTR_ERR(handle);
4260 break; 4268 break;
4261 } 4269 }
4262 ret = ext4_map_blocks(handle, inode, &map, 4270 ret = ext4_map_blocks(handle, inode, &map, flags);
4263 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT |
4264 EXT4_GET_BLOCKS_NO_NORMALIZE);
4265 if (ret <= 0) { 4271 if (ret <= 0) {
4266#ifdef EXT4FS_DEBUG 4272#ifdef EXT4FS_DEBUG
4267 WARN_ON(ret <= 0); 4273 WARN_ON(ret <= 0);