On 9/14/11 2:16 AM, Tao Ma wrote: > From: Tao Ma <boyu.mt@xxxxxxxxxx> > > 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. Argh, yes, I think you are right. Pesky else clause. :( Do you have a testcase for this? And what is the user-visible outcome of the error, is it data corruption? > Cc: Eric Sandeen <sandeen@xxxxxxxxxx> > Cc: "Theodore Ts'o" <tytso@xxxxxxx> > Signed-off-by: Tao Ma <boyu.mt@xxxxxxxxxx> > --- > fs/ext4/extents.c | 16 ++++++++++------ > 1 files changed, 10 insertions(+), 6 deletions(-) > > diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c > index 57cf568..8db6743 100644 > --- a/fs/ext4/extents.c > +++ b/fs/ext4/extents.c > @@ -3190,9 +3190,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)) > @@ -3572,9 +3574,11 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, > * 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); -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html