From: Zhang Xiaoxu zhangxiaoxu5@huawei.com
hulk inclusion category: feature bugzilla: 185871, https://gitee.com/openeuler/kernel/issues/I4MIQ0 CVE: NA
---------------------------
This reverts commit bb24e7e6309ae1bbc80062366b8f9bb2e8fcc025.
In order to improve the dio reads performance, we enable the parallel dio reads.
And make it configuratable
Conflict: fs/ext4/Kconfig fs/ext4/inode.c
Signed-off-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/Kconfig | 5 +++++ fs/ext4/inode.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index a453cc87082b5..de836b75c6f2b 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -120,3 +120,8 @@ config EXT4_DEBUG If you select Y here, then you will be able to turn on debugging with a command such as: echo 1 > /sys/module/ext4/parameters/mballoc_debug +config EXT4_PARALLEL_DIO_READ + bool "EXT4 parallel dio reads" + depends on EXT4_FS + help + Enable parallel dio read. diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index fb4de707cd9ad..2f5231899d342 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3795,15 +3795,31 @@ static ssize_t ext4_direct_IO_write(struct kiocb *iocb, struct iov_iter *iter)
static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) { + struct address_space *mapping = iocb->ki_filp->f_mapping; + struct inode *inode = mapping->host; +#ifdef CONFIG_EXT4_PARALLEL_DIO_READ + size_t count = iov_iter_count(iter); +#else int unlocked = 0; - struct inode *inode = iocb->ki_filp->f_mapping->host; +#endif ssize_t ret; loff_t offset = iocb->ki_pos; loff_t size = i_size_read(inode);
if (offset >= size) return 0; - +#ifdef CONFIG_EXT4_PARALLEL_DIO_READ + /* + * Shared inode_lock is enough for us - it protects against concurrent + * writes & truncates and since we take care of writing back page cache, + * we are protected against page writeback as well. + */ + inode_lock_shared(inode); + ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, + iocb->ki_pos + count - 1); + if (ret) + goto out_unlock; +#else if (ext4_should_dioread_nolock(inode)) { /* * Nolock dioread optimization may be dynamically disabled @@ -3813,18 +3829,24 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) inode_dio_begin(inode); smp_mb(); if (unlikely(ext4_test_inode_state(inode, - EXT4_STATE_DIOREAD_LOCK))) + EXT4_STATE_DIOREAD_LOCK))) inode_dio_end(inode); else unlocked = 1; } +#endif + ret = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, - iter, ext4_dio_get_block, - NULL, NULL, + iter, ext4_dio_get_block, NULL, NULL, +#ifdef CONFIG_EXT4_PARALLEL_DIO_READ + 0); +out_unlock: + inode_unlock_shared(inode); +#else unlocked ? 0 : DIO_LOCKING); - if (unlocked) inode_dio_end(inode); +#endif return ret; }