summaryrefslogtreecommitdiff
path: root/fs/ext4
diff options
context:
space:
mode:
authorTao Ma <boyu.mt@taobao.com>2011-10-26 11:08:39 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-10-26 11:08:39 -0400
commitb3ff05690845911cc40387176f0bc5a7af9ef3ff (patch)
tree9ed6230ae4616d67d85aed9e9b8dc6477642312c /fs/ext4
parent0a10da73e1fa6fb9b45f1166011ff3b04c27c010 (diff)
downloadlwn-b3ff05690845911cc40387176f0bc5a7af9ef3ff.tar.gz
lwn-b3ff05690845911cc40387176f0bc5a7af9ef3ff.zip
ext4: don't check io->flag when setting EXT4_STATE_DIO_UNWRITTEN inode state
When we want to convert the unitialized extent in direct write, we can either do it in ext4_end_io_nolock(AIO case) or in ext4_ext_direct_IO(non AIO case) and EXT4_I(inode)->cur_aio_dio is a guard for ext4_ext_map_blocks to find the right case. In e9e3bcecf, we mistakenly change it by: - if (io) + if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) { io->flag = EXT4_IO_END_UNWRITTEN; - else + atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten); + } else ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN); So now if we map 2 blocks, and the first one set the EXT_IO_END_UNWRITTEN, the 2nd mapping will set inode state because of the check for the flag. This is wrong. Cc: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Tao Ma <boyu.mt@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/extents.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 797b63b59740..c2ac06cb2d46 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3390,9 +3390,11 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
* that this IO needs to conversion to written when IO is
* completed
*/
- if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) {
- io->flag = EXT4_IO_END_UNWRITTEN;
- atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+ if (io) {
+ if (!(io->flag & EXT4_IO_END_UNWRITTEN)) {
+ io->flag = EXT4_IO_END_UNWRITTEN;
+ atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+ }
} else
ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
if (ext4_should_dioread_nolock(inode))
@@ -3946,9 +3948,11 @@ got_allocated_blocks:
* that we need to perform conversion when IO is done.
*/
if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
- if (io && !(io->flag & EXT4_IO_END_UNWRITTEN)) {
- io->flag = EXT4_IO_END_UNWRITTEN;
- atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+ if (io) {
+ if (!(io->flag & EXT4_IO_END_UNWRITTEN)) {
+ io->flag = EXT4_IO_END_UNWRITTEN;
+ atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+ }
} else
ext4_set_inode_state(inode,
EXT4_STATE_DIO_UNWRITTEN);