summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2012-10-05 11:32:02 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-10-05 11:32:02 -0400
commit60d4616f3dc63371b3dc367e5e88fd4b4f037f65 (patch)
tree1365c73827aa4efd95d805e314f13182366d1251 /fs
parentc278531d39f3158bfee93dc67da0b77e09776de2 (diff)
downloadlinux-stable-60d4616f3dc63371b3dc367e5e88fd4b4f037f65.tar.gz
linux-stable-60d4616f3dc63371b3dc367e5e88fd4b4f037f65.tar.bz2
linux-stable-60d4616f3dc63371b3dc367e5e88fd4b4f037f65.zip
ext4: serialize fallocate with ext4_convert_unwritten_extents
Fallocate should wait for pended ext4_convert_unwritten_extents() otherwise following race may happen: ftruncate( ,12288); fallocate( ,0, 4096) io_sibmit( ,0, 4096); /* Write to fallocated area, split extent if needed */ fallocate( ,0, 8192); /* Grow extent and broke assumption about extent */ Later kwork completion will do: ->ext4_convert_unwritten_extents (0, 4096) ->ext4_map_blocks(handle, inode, &map, EXT4_GET_BLOCKS_IO_CONVERT_EXT); ->ext4_ext_map_blocks() /* Will find new extent: ex = [0,2] !!!!!! */ ->ext4_ext_handle_uninitialized_extents() ->ext4_convert_unwritten_extents_endio() /* convert [0,2] extent to initialized, but only[0,1] was written */ Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/extents.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 1c94cca35ed1..c2789271e7b4 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4428,6 +4428,9 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
*/
if (len <= EXT_UNINIT_MAX_LEN << blkbits)
flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
+
+ /* Prevent race condition between unwritten */
+ ext4_flush_unwritten_io(inode);
retry:
while (ret >= 0 && ret < max_blocks) {
map.m_lblk = map.m_lblk + ret;