ext4: add dio overwrite nolock]
RFC PATCH 3/3 ext4: add dio overwrite nolock]
[Sorry, when I reply this mail to the mailing list, I get an error. So I resend it to the mailing list.]
----- Forwarded message from Zheng Liu <[email protected]> -----
Date: Wed, 2 May 2012 23:49:35 +0800
From: Zheng Liu <[email protected]>
To: Eric Sandeen <[email protected]>
Cc: "[email protected]" <[email protected]>, Zheng Liu <[email protected]>
Subject: Re: [RFC][PATCH 3/3] ext4: add dio overwrite nolock
Quoted 12 lines · Eric Sandeen
Quoted 3 lines · Zheng Liu
From: Zheng Liu <[email protected] <javascript:;>>
Aligned and overwrite direct IO can be parallelized. In
ext4_file_dio_write,Quoted 1 line
we first check whether these conditions are satisfied or not. If so, we
unlock
Quoted 1 line
the
i_mutexand acquirei_data_semdirectly. Meanwhileiocb->privateisset to
Quoted 2 lines
indicate that this is a overwrite dio, and it will be processed in
ext4_ext_direct_IO.
Quoted 7 lines
This copies almost 100 lines of
generic_file_aio_write()back into ext4. Do we really need to do this? Copying core code into the fs can be a maintenance nightmare...I'll have to think more about the big picture and whether or not it's possible, but my first reaction is to find a way to leverage or modify existing IO code rather than pasting it all into ext4 with changes...
The key issue is file_update_time. In this function, it starts a new journal. It will cause a deadlock because we usually start a new journal firstly, and then try to lock i_data_sem. But in overwrite this order is reversed. If we can avoid this deadlock, we won't need to copy core code into ext4.
Regards,
Zheng
Quoted 88 lines
-Eric
Quoted 3 lines
Signed-off-by Zheng Liu <[email protected]>--- fs/ext4/file.c | 140++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Quoted 20 lines
1 files changed, 137 insertions(+), 3 deletions(-)fs/ext4/file.c +7
-2@@ -100,9 +100,21 @@ static ssize_t ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { - struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; -int unaligned_aio =0 ; + struct file *file = iocb->ki_filp; +struct address_space * mapping = file->f_mapping; +struct inode *inode = file->f_path.dentry->d_inode; +struct blk_plug plug;ssize_t ret; +ssize_t written, written_buffered; +size_t length =iov_length (iov, nr_segs); +size_t ocount;/* original count */ fs/ext4/file.c static ssize_t · line 120
Quoted 10 lines
fs/ext4/file.c +7
-0+size_t count;/* after file limit checks */ +int unaligned_aio =0 ; +int overwrite =0 ; +loff_t *ppos = &iocb->ki_pos; +loff_t endbyte; + +BUG_ON (iocb->ki_pos != pos);if (!is_sync_kiocb (iocb)) unaligned_aio = ext4_unaligned_aio(inode, iov, nr_segs,pos);
fs/ext4/file.c ext4_file_dio_write(struct kiocb *iocb, const
Quoted 1 line
fs/ext4/file.c +0
-0@@ -121,7 +133,129 @@ ext4_file_dio_write(struct kiocb *iocb, conststruct iovec *iov,
Quoted 12 lines
fs/ext4/file.c +8
-1ext4_aiodio_wait (inode); } - ret =generic_file_aio_write (iocb, iov, nr_segs, pos); +mutex_lock (&inode->i_mutex); +blk_start_plug (&plug); + + ocount =0 ; + ret =generic_segment_checks (iov, &nr_segs, &ocount,VERIFY_READ ); +if (ret) + goto unlock_out; +fs/ext4/file.c ext4_file_dio_write(struct kiocb *iocb, const · line 153
Quoted 10 lines
fs/ext4/file.c +10
-0+ count = ocount; + pos = *ppos; + +vfs_check_frozen (inode->i_sb,SB_FREEZE_WRITE ); + +/* We can write back this queue in page reclaim */ + current->backing_dev_info = mapping->backing_dev_info; + written =0 ; + + ret = generic_write_checks(file, &pos, &count,
S_ISBLK(inode->i_mode));Quoted 14 lines
fs/ext4/file.c +14
-0+if (ret) + goto out; + +if (count ==0 ) + goto out; + + ret =file_remove_suid (file); +if (ret) + goto out; + +file_update_time (file); + + iocb->private =NULL ; +fs/ext4/file.c ext4_file_dio_write(struct kiocb *iocb, const · line 177
Quoted 10 lines
fs/ext4/file.c +10
-0+if (!unaligned_aio && !file->f_mapping->nrpages && + pos + length <i_size_read (inode) && +ext4_should_dioread_nolock (inode)) { +struct ext4_map_blocks map; +unsigned int blkbits = inode->i_blkbits; +int err; +int len; + + map.m_lblk = pos >> blkbits; + map.m_len = (EXT4_BLOCK_ALIGN(pos + length, blkbits) >>blkbits)
Quoted 7 lines
fs/ext4/file.c ext4_file_dio_write(struct kiocb *iocb, const · line 184
Quoted 7 lines
fs/ext4/file.c +7
-0+ - map.m_lblk; + len = map.m_len; + + err =ext4_map_blocks (NULL , inode, &map,0 ); +if (err == len && (!map.m_flags || + map.m_flags &EXT4_MAP_MAPPED )) { +
----- End forwarded message -----