Hi Mingming: On Thu, Oct 8, 2009 at 6:13 PM, Mingming <cmm@xxxxxxxxxx> wrote: > ext4: avoid perform unwritten convertion for direct IO over non fallocated space > > When direct IO complete, without this patch, it always check and convert > the range covered by the completed IO to be written. This is unnecessary > if the range doesn't has any preallocated area or holes. This patch add > a state flag to alart direct IO code to only run the convertion when > there is unwritten extents being covered in this IO. > > Signed-off-by: Mingming Cao <cmm@xxxxxxxxxx> > --- > fs/ext4/ext4.h | 1 + > fs/ext4/extents.c | 22 +++++++++++++++++----- > fs/ext4/inode.c | 4 +++- > 3 files changed, 21 insertions(+), 6 deletions(-) > > Index: linux-2.6.31-rc4/fs/ext4/ext4.h > =================================================================== > --- linux-2.6.31-rc4.orig/fs/ext4/ext4.h > +++ linux-2.6.31-rc4/fs/ext4/ext4.h > @@ -299,6 +299,7 @@ static inline __u32 ext4_mask_flags(umod > #define EXT4_STATE_XATTR 0x00000004 /* has in-inode xattrs */ > #define EXT4_STATE_NO_EXPAND 0x00000008 /* No space for expansion */ > #define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010 /* Alloc DA blks on close */ > +#define EXT4_STATE_DIO_UNWRITTEN 0x00000020 /* need convert on dio done*/ You'll need to change this value, since EXT4_STATE_EXT_MIGRATE has already been assigned 0x20. Thanks, Curt > > /* Used to pass group descriptor data when online resize is done */ > struct ext4_new_group_input { > Index: linux-2.6.31-rc4/fs/ext4/extents.c > =================================================================== > --- linux-2.6.31-rc4.orig/fs/ext4/extents.c > +++ linux-2.6.31-rc4/fs/ext4/extents.c > @@ -3029,12 +3029,18 @@ ext4_ext_handle_uninitialized_extents(ha > ret = ext4_split_unwritten_extents(handle, > inode, path, iblock, > max_blocks, flags); > - /* flag the io_end struct that we need convert when IO done */ > + /* > + * Flag the inode(non aio case) or end_io struct (aio case) > + * that this IO needs to convertion to written when IO is > + * completed > + */ > if (io) > io->flag = DIO_AIO_UNWRITTEN; > + else > + EXT4_I(inode)->i_state |= EXT4_STATE_DIO_UNWRITTEN; > goto out; > } > - /* DIO end_io complete, convert the filled extent to written */ > + /* async DIO end_io complete, convert the filled extent to written */ > if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) { > ret = ext4_convert_unwritten_extents_dio(handle, inode, > path); > @@ -3276,10 +3282,16 @@ int ext4_ext_get_blocks(handle_t *handle > * To avoid unecessary convertion for every aio dio rewrite > * to the mid of file, here we flag the IO that is really > * need the convertion. > - * > + * For non asycn direct IO case, flag the inode state > + * that we need to perform convertion when IO is done. > */ > - if (io && flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) > - io->flag = DIO_AIO_UNWRITTEN; > + if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) { > + if (io) > + io->flag = DIO_AIO_UNWRITTEN; > + else > + EXT4_I(inode)->i_state |= > + EXT4_STATE_DIO_UNWRITTEN;; > + } > } > err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); > if (err) { > Index: linux-2.6.31-rc4/fs/ext4/inode.c > =================================================================== > --- linux-2.6.31-rc4.orig/fs/ext4/inode.c > +++ linux-2.6.31-rc4/fs/ext4/inode.c > @@ -3693,7 +3693,8 @@ static ssize_t ext4_ext_direct_IO(int rw > if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) { > ext4_free_io_end(iocb->private); > iocb->private = NULL; > - } else if (ret > 0){ > + } else if (ret > 0 && EXT4_I(inode)->i_state & > + EXT4_STATE_DIO_UNWRITTEN){ > int err; > /* > * for non AIO case, since the IO is already > @@ -3703,6 +3704,7 @@ static ssize_t ext4_ext_direct_IO(int rw > offset, ret); > if (err < 0) > ret = err; > + EXT4_I(inode)->i_state &= ~EXT4_STATE_DIO_UNWRITTEN; > } > return ret; > } > > > -- 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