fs/ext4/ext4.h | 14 +- fs/ext4/ext4_jbd2.c | 6 + fs/ext4/ext4_jbd2.h | 7 + fs/ext4/extents.c | 149 +++--- fs/ext4/extents_status.c | 39 +- fs/ext4/extents_status.h | 4 +- fs/ext4/file.c | 19 +- fs/ext4/ialloc.c | 5 + fs/ext4/inode.c | 891 +++++++++++++++++++++++++++--------- fs/ext4/move_extent.c | 35 ++ fs/ext4/page-io.c | 107 +++++ fs/ext4/super.c | 3 + fs/iomap/buffered-io.c | 30 +- fs/iomap/trace.h | 43 +- include/linux/pagemap.h | 14 + include/trace/events/ext4.h | 31 +- mm/readahead.c | 6 +- 17 files changed, 1109 insertions(+), 294 deletions(-)
From: Zhang Yi <yi.zhang@huawei.com>
Hello,
This is the third version of RFC patch series that convert ext4 regular
file's buffered IO path to iomap and enable large folio. It's rebased on
6.7 and Christoph's "map multiple blocks per ->map_blocks in iomap
writeback" series [1]. I've fixed all issues found in the last about 3
weeks of stress tests and fault injection tests in v2. I hope I've
covered most of the corner cases, and any comments are welcome. :)
Changes since v2:
- Update patch 1-6 to v3 [2].
- iomap_zero and iomap_unshare don't need to update i_size and call
iomap_write_failed(), introduce a new helper iomap_write_end_simple()
to avoid doing that.
- Factor out ext4_[ext|ind]_map_blocks() parts from ext4_map_blocks(),
introduce a new helper ext4_iomap_map_one_extent() to allocate
delalloc blocks in writeback, which is always under i_data_sem in
write mode. This is done to prevent the writing back delalloc
extents become stale if it raced by truncate.
- Add a lock detection in mapping_clear_large_folios().
Changes since v1:
- Introduce seq count for iomap buffered write and writeback to protect
races from extents changes, e.g. truncate, mwrite.
- Always allocate unwritten extents for new blocks, drop dioread_lock
mode, and make no distinctions between dioread_lock and
dioread_nolock.
- Don't add ditry data range to jinode, drop data=ordered mode, and
make no distinctions between data=ordered and data=writeback mode.
- Postpone updating i_disksize to endio.
- Allow splitting extents and use reserved space in endio.
- Instead of reimplement a new delayed mapping helper
ext4_iomap_da_map_blocks() for buffer write, try to reuse
ext4_da_map_blocks().
- Add support for disabling large folio on active inodes.
- Support online defragmentation, make file fall back to buffer_head
and disable large folio in ext4_move_extents().
- Move ext4_nonda_switch() in advance to prevent deadlock in mwrite.
- Add dirty_len and pos trace info to trace_iomap_writepage_map().
- Update patch 1-6 to v2.
This series only support ext4 with the default features and mount
options, doesn't support inline_data, bigalloc, dax, fs_verity, fs_crypt
and data=journal mode, ext4 would fall back to buffer_head path
automatically if you enabled these features/options. Although it has
many limitations now, it can satisfy the requirements of common cases
and bring a great performance benefit.
Patch 1-6: this is a preparation series, it changes ext4_map_blocks()
and ext4_set_iomap() to recognize delayed only extents, I've send it out
separately [2].
Patch 7-8: these are two minor iomap changes, the first one is don't
update i_size and don't call iomap_write_failed() in zero_range, the
second one is for debug in iomap writeback path that I've discussed whit
Christoph [3].
Patch 9-15: this is another preparation series, including some changes
for delayed extents. Firstly, it factor out buffer_head from
ext4_da_map_blocks(), make it to support adding multi-blocks once a
time. Then make unwritten to written extents conversion in endio use to
reserved space, reduce the risk of potential data loss. Finally,
introduce a sequence counter for extent status tree, which is useful
for iomap buffer write and write back.
Patch 16-22: Implement buffered IO iomap path for read, write, mmap,
zero range, truncate and writeback, replace current buffered_head path.
Please look at the following patch for details.
Patch 23-26: Convert to iomap for regular file's buffered IO path
besides inline_data, bigalloc, dax, fs_verity, fs_crypt, and
data=journal mode, and enable large folio. It should be note that
buffered iomap path hasn't support Online defrag yet, so we need fall
back to buffer_head and disable large folio automatically if user call
EXT4_IOC_MOVE_EXT.
About Tests:
- kvm-xfstests in auto mode, and about 3 weeks of stress tests and
fault injection tests.
- A performance tests below.
Fio tests with psync on my machine with Intel Xeon Gold 6240 CPU
with 400GB system ram, 200GB ramdisk and 1TB nvme ssd disk.
== buffer read ==
buffer head iomap with large folio
type bs IOPS BW(MiB/s) IOPS BW(MiB/s)
----------------------------------------------------
hole 4K 565k 2206 811k 3167
hole 64K 45.1k 2820 78.1k 4879
hole 1M 2744 2744 4890 4891
ramdisk 4K 436k 1703 554k 2163
ramdisk 64K 29.6k 1848 44.0k 2747
ramdisk 1M 1994 1995 2809 2809
nvme 4K 306k 1196 324k 1267
nvme 64K 19.3k 1208 24.3k 1517
nvme 1M 1694 1694 2256 2256
== buffer write ==
buffer head ext4_iomap
type Overwrite Sync Writeback bs IOPS BW IOPS BW
-------------------------------------------------------------
cache N N N 4K 395k 1544 415k 1621
cache N N N 64K 30.8k 1928 80.1k 5005
cache N N N 1M 1963 1963 5641 5642
cache Y N N 4K 423k 1652 443k 1730
cache Y N N 64K 33.0k 2063 80.8k 5051
cache Y N N 1M 2103 2103 5588 5589
ramdisk N N Y 4K 362k 1416 307k 1198
ramdisk N N Y 64K 22.4k 1399 64.8k 4050
ramdisk N N Y 1M 1670 1670 4559 4560
ramdisk N Y N 4K 9830 38.4 13.5k 52.8
ramdisk N Y N 64K 5834 365 10.1k 629
ramdisk N Y N 1M 1011 1011 2064 2064
ramdisk Y N Y 4K 397k 1550 409k 1598
ramdisk Y N Y 64K 29.2k 1827 73.6k 4597
ramdisk Y N Y 1M 1837 1837 4985 4985
ramdisk Y Y N 4K 173k 675 182k 710
ramdisk Y Y N 64K 17.7k 1109 33.7k 2105
ramdisk Y Y N 1M 1128 1129 1790 1791
nvme N N Y 4K 298k 1164 290k 1134
nvme N N Y 64K 21.5k 1343 57.4k 3590
nvme N N Y 1M 1308 1308 3664 3664
nvme N Y N 4K 10.7k 41.8 12.0k 46.9
nvme N Y N 64K 5962 373 8598 537
nvme N Y N 1M 676 677 1417 1418
nvme Y N Y 4K 366k 1430 373k 1456
nvme Y N Y 64K 26.7k 1670 56.8k 3547
nvme Y N Y 1M 1745 1746 3586 3586
nvme Y Y N 4K 59.0k 230 61.2k 239
nvme Y Y N 64K 13.0k 813 21.0k 1311
nvme Y Y N 1M 683 683 1368 1369
TODO
- Keep on doing stress tests and fixing.
- I will rebase and resend my another patch set "ext4: more accurate
metadata reservaion for delalloc mount option[4]" later, it's useful
for iomap conversion. After this series, I suppose we could totally
drop ext4_nonda_switch() and prevent the risk of data loss caused by
extents splitting.
- Support for more features and mount options in the future.
[1] https://lore.kernel.org/linux-fsdevel/20231207072710.176093-1-hch@lst.de/
[2] https://lore.kernel.org/linux-ext4/20240105033018.1665752-1-yi.zhang@huaweicloud.com/
[3] https://lore.kernel.org/linux-fsdevel/20231207150311.GA18830@lst.de/
[4] https://lore.kernel.org/linux-ext4/20230824092619.1327976-1-yi.zhang@huaweicloud.com/
Thanks,
Yi.
---
v2: https://lore.kernel.org/linux-ext4/20240102123918.799062-1-yi.zhang@huaweicloud.com/
v1: https://lore.kernel.org/linux-ext4/20231123125121.4064694-1-yi.zhang@huaweicloud.com/
Zhang Yi (26):
ext4: refactor ext4_da_map_blocks()
ext4: convert to exclusive lock while inserting delalloc extents
ext4: correct the hole length returned by ext4_map_blocks()
ext4: add a hole extent entry in cache after punch
ext4: make ext4_map_blocks() distinguish delalloc only extent
ext4: make ext4_set_iomap() recognize IOMAP_DELALLOC map type
iomap: don't increase i_size if it's not a write operation
iomap: add pos and dirty_len into trace_iomap_writepage_map
ext4: allow inserting delalloc extents with multi-blocks
ext4: correct delalloc extent length
ext4: also mark extent as delalloc if it's been unwritten
ext4: factor out bh handles to ext4_da_get_block_prep()
ext4: use reserved metadata blocks when splitting extent in endio
ext4: factor out ext4_map_{create|query}_blocks()
ext4: introduce seq counter for extent entry
ext4: add a new iomap aops for regular file's buffered IO path
ext4: implement buffered read iomap path
ext4: implement buffered write iomap path
ext4: implement writeback iomap path
ext4: implement mmap iomap path
ext4: implement zero_range iomap path
ext4: writeback partial blocks before zero range
ext4: fall back to buffer_head path for defrag
ext4: partially enable iomap for regular file's buffered IO path
filemap: support disable large folios on active inode
ext4: enable large folio for regular file with iomap buffered IO path
fs/ext4/ext4.h | 14 +-
fs/ext4/ext4_jbd2.c | 6 +
fs/ext4/ext4_jbd2.h | 7 +
fs/ext4/extents.c | 149 +++---
fs/ext4/extents_status.c | 39 +-
fs/ext4/extents_status.h | 4 +-
fs/ext4/file.c | 19 +-
fs/ext4/ialloc.c | 5 +
fs/ext4/inode.c | 891 +++++++++++++++++++++++++++---------
fs/ext4/move_extent.c | 35 ++
fs/ext4/page-io.c | 107 +++++
fs/ext4/super.c | 3 +
fs/iomap/buffered-io.c | 30 +-
fs/iomap/trace.h | 43 +-
include/linux/pagemap.h | 14 +
include/trace/events/ext4.h | 31 +-
mm/readahead.c | 6 +-
17 files changed, 1109 insertions(+), 294 deletions(-)
--
2.39.2
On Sat, Jan 27, 2024 at 09:57:59AM +0800, Zhang Yi wrote:
> From: Zhang Yi <yi.zhang@huawei.com>
>
> Hello,
>
> This is the third version of RFC patch series that convert ext4 regular
> file's buffered IO path to iomap and enable large folio. It's rebased on
> 6.7 and Christoph's "map multiple blocks per ->map_blocks in iomap
> writeback" series [1]. I've fixed all issues found in the last about 3
> weeks of stress tests and fault injection tests in v2. I hope I've
> covered most of the corner cases, and any comments are welcome. :)
>
> Changes since v2:
> - Update patch 1-6 to v3 [2].
> - iomap_zero and iomap_unshare don't need to update i_size and call
> iomap_write_failed(), introduce a new helper iomap_write_end_simple()
> to avoid doing that.
> - Factor out ext4_[ext|ind]_map_blocks() parts from ext4_map_blocks(),
> introduce a new helper ext4_iomap_map_one_extent() to allocate
> delalloc blocks in writeback, which is always under i_data_sem in
> write mode. This is done to prevent the writing back delalloc
> extents become stale if it raced by truncate.
> - Add a lock detection in mapping_clear_large_folios().
> Changes since v1:
> - Introduce seq count for iomap buffered write and writeback to protect
> races from extents changes, e.g. truncate, mwrite.
> - Always allocate unwritten extents for new blocks, drop dioread_lock
> mode, and make no distinctions between dioread_lock and
> dioread_nolock.
> - Don't add ditry data range to jinode, drop data=ordered mode, and
> make no distinctions between data=ordered and data=writeback mode.
> - Postpone updating i_disksize to endio.
> - Allow splitting extents and use reserved space in endio.
> - Instead of reimplement a new delayed mapping helper
> ext4_iomap_da_map_blocks() for buffer write, try to reuse
> ext4_da_map_blocks().
> - Add support for disabling large folio on active inodes.
> - Support online defragmentation, make file fall back to buffer_head
> and disable large folio in ext4_move_extents().
> - Move ext4_nonda_switch() in advance to prevent deadlock in mwrite.
> - Add dirty_len and pos trace info to trace_iomap_writepage_map().
> - Update patch 1-6 to v2.
>
> This series only support ext4 with the default features and mount
> options, doesn't support inline_data, bigalloc, dax, fs_verity, fs_crypt
> and data=journal mode, ext4 would fall back to buffer_head path
Do you plan to add bigalloc or !extents support as a part 2 patchset?
An ext2 port to iomap has been (vaguely) in the works for a while,
though iirc willy never got the performance to match because iomap
didn't have a mechanism for the caller to tell it "run the IO now even
though you don't have a complete page, because the indirect block is the
next block after the 11th block".
--D
> automatically if you enabled these features/options. Although it has
> many limitations now, it can satisfy the requirements of common cases
> and bring a great performance benefit.
>
> Patch 1-6: this is a preparation series, it changes ext4_map_blocks()
> and ext4_set_iomap() to recognize delayed only extents, I've send it out
> separately [2].
>
> Patch 7-8: these are two minor iomap changes, the first one is don't
> update i_size and don't call iomap_write_failed() in zero_range, the
> second one is for debug in iomap writeback path that I've discussed whit
> Christoph [3].
>
> Patch 9-15: this is another preparation series, including some changes
> for delayed extents. Firstly, it factor out buffer_head from
> ext4_da_map_blocks(), make it to support adding multi-blocks once a
> time. Then make unwritten to written extents conversion in endio use to
> reserved space, reduce the risk of potential data loss. Finally,
> introduce a sequence counter for extent status tree, which is useful
> for iomap buffer write and write back.
>
> Patch 16-22: Implement buffered IO iomap path for read, write, mmap,
> zero range, truncate and writeback, replace current buffered_head path.
> Please look at the following patch for details.
>
> Patch 23-26: Convert to iomap for regular file's buffered IO path
> besides inline_data, bigalloc, dax, fs_verity, fs_crypt, and
> data=journal mode, and enable large folio. It should be note that
> buffered iomap path hasn't support Online defrag yet, so we need fall
> back to buffer_head and disable large folio automatically if user call
> EXT4_IOC_MOVE_EXT.
>
> About Tests:
> - kvm-xfstests in auto mode, and about 3 weeks of stress tests and
> fault injection tests.
> - A performance tests below.
>
> Fio tests with psync on my machine with Intel Xeon Gold 6240 CPU
> with 400GB system ram, 200GB ramdisk and 1TB nvme ssd disk.
>
> == buffer read ==
>
> buffer head iomap with large folio
> type bs IOPS BW(MiB/s) IOPS BW(MiB/s)
> ----------------------------------------------------
> hole 4K 565k 2206 811k 3167
> hole 64K 45.1k 2820 78.1k 4879
> hole 1M 2744 2744 4890 4891
> ramdisk 4K 436k 1703 554k 2163
> ramdisk 64K 29.6k 1848 44.0k 2747
> ramdisk 1M 1994 1995 2809 2809
> nvme 4K 306k 1196 324k 1267
> nvme 64K 19.3k 1208 24.3k 1517
> nvme 1M 1694 1694 2256 2256
>
> == buffer write ==
>
> buffer head ext4_iomap
> type Overwrite Sync Writeback bs IOPS BW IOPS BW
> -------------------------------------------------------------
> cache N N N 4K 395k 1544 415k 1621
> cache N N N 64K 30.8k 1928 80.1k 5005
> cache N N N 1M 1963 1963 5641 5642
> cache Y N N 4K 423k 1652 443k 1730
> cache Y N N 64K 33.0k 2063 80.8k 5051
> cache Y N N 1M 2103 2103 5588 5589
> ramdisk N N Y 4K 362k 1416 307k 1198
> ramdisk N N Y 64K 22.4k 1399 64.8k 4050
> ramdisk N N Y 1M 1670 1670 4559 4560
> ramdisk N Y N 4K 9830 38.4 13.5k 52.8
> ramdisk N Y N 64K 5834 365 10.1k 629
> ramdisk N Y N 1M 1011 1011 2064 2064
> ramdisk Y N Y 4K 397k 1550 409k 1598
> ramdisk Y N Y 64K 29.2k 1827 73.6k 4597
> ramdisk Y N Y 1M 1837 1837 4985 4985
> ramdisk Y Y N 4K 173k 675 182k 710
> ramdisk Y Y N 64K 17.7k 1109 33.7k 2105
> ramdisk Y Y N 1M 1128 1129 1790 1791
> nvme N N Y 4K 298k 1164 290k 1134
> nvme N N Y 64K 21.5k 1343 57.4k 3590
> nvme N N Y 1M 1308 1308 3664 3664
> nvme N Y N 4K 10.7k 41.8 12.0k 46.9
> nvme N Y N 64K 5962 373 8598 537
> nvme N Y N 1M 676 677 1417 1418
> nvme Y N Y 4K 366k 1430 373k 1456
> nvme Y N Y 64K 26.7k 1670 56.8k 3547
> nvme Y N Y 1M 1745 1746 3586 3586
> nvme Y Y N 4K 59.0k 230 61.2k 239
> nvme Y Y N 64K 13.0k 813 21.0k 1311
> nvme Y Y N 1M 683 683 1368 1369
>
> TODO
> - Keep on doing stress tests and fixing.
> - I will rebase and resend my another patch set "ext4: more accurate
> metadata reservaion for delalloc mount option[4]" later, it's useful
> for iomap conversion. After this series, I suppose we could totally
> drop ext4_nonda_switch() and prevent the risk of data loss caused by
> extents splitting.
> - Support for more features and mount options in the future.
>
> [1] https://lore.kernel.org/linux-fsdevel/20231207072710.176093-1-hch@lst.de/
> [2] https://lore.kernel.org/linux-ext4/20240105033018.1665752-1-yi.zhang@huaweicloud.com/
> [3] https://lore.kernel.org/linux-fsdevel/20231207150311.GA18830@lst.de/
> [4] https://lore.kernel.org/linux-ext4/20230824092619.1327976-1-yi.zhang@huaweicloud.com/
>
> Thanks,
> Yi.
>
> ---
> v2: https://lore.kernel.org/linux-ext4/20240102123918.799062-1-yi.zhang@huaweicloud.com/
> v1: https://lore.kernel.org/linux-ext4/20231123125121.4064694-1-yi.zhang@huaweicloud.com/
>
> Zhang Yi (26):
> ext4: refactor ext4_da_map_blocks()
> ext4: convert to exclusive lock while inserting delalloc extents
> ext4: correct the hole length returned by ext4_map_blocks()
> ext4: add a hole extent entry in cache after punch
> ext4: make ext4_map_blocks() distinguish delalloc only extent
> ext4: make ext4_set_iomap() recognize IOMAP_DELALLOC map type
> iomap: don't increase i_size if it's not a write operation
> iomap: add pos and dirty_len into trace_iomap_writepage_map
> ext4: allow inserting delalloc extents with multi-blocks
> ext4: correct delalloc extent length
> ext4: also mark extent as delalloc if it's been unwritten
> ext4: factor out bh handles to ext4_da_get_block_prep()
> ext4: use reserved metadata blocks when splitting extent in endio
> ext4: factor out ext4_map_{create|query}_blocks()
> ext4: introduce seq counter for extent entry
> ext4: add a new iomap aops for regular file's buffered IO path
> ext4: implement buffered read iomap path
> ext4: implement buffered write iomap path
> ext4: implement writeback iomap path
> ext4: implement mmap iomap path
> ext4: implement zero_range iomap path
> ext4: writeback partial blocks before zero range
> ext4: fall back to buffer_head path for defrag
> ext4: partially enable iomap for regular file's buffered IO path
> filemap: support disable large folios on active inode
> ext4: enable large folio for regular file with iomap buffered IO path
>
> fs/ext4/ext4.h | 14 +-
> fs/ext4/ext4_jbd2.c | 6 +
> fs/ext4/ext4_jbd2.h | 7 +
> fs/ext4/extents.c | 149 +++---
> fs/ext4/extents_status.c | 39 +-
> fs/ext4/extents_status.h | 4 +-
> fs/ext4/file.c | 19 +-
> fs/ext4/ialloc.c | 5 +
> fs/ext4/inode.c | 891 +++++++++++++++++++++++++++---------
> fs/ext4/move_extent.c | 35 ++
> fs/ext4/page-io.c | 107 +++++
> fs/ext4/super.c | 3 +
> fs/iomap/buffered-io.c | 30 +-
> fs/iomap/trace.h | 43 +-
> include/linux/pagemap.h | 14 +
> include/trace/events/ext4.h | 31 +-
> mm/readahead.c | 6 +-
> 17 files changed, 1109 insertions(+), 294 deletions(-)
>
> --
> 2.39.2
>
>
On 2024/2/12 14:18, Darrick J. Wong wrote: > On Sat, Jan 27, 2024 at 09:57:59AM +0800, Zhang Yi wrote: >> From: Zhang Yi <yi.zhang@huawei.com> >> >> Hello, >> >> This is the third version of RFC patch series that convert ext4 regular >> file's buffered IO path to iomap and enable large folio. It's rebased on >> 6.7 and Christoph's "map multiple blocks per ->map_blocks in iomap >> writeback" series [1]. I've fixed all issues found in the last about 3 >> weeks of stress tests and fault injection tests in v2. I hope I've >> covered most of the corner cases, and any comments are welcome. :) >> >> Changes since v2: >> - Update patch 1-6 to v3 [2]. >> - iomap_zero and iomap_unshare don't need to update i_size and call >> iomap_write_failed(), introduce a new helper iomap_write_end_simple() >> to avoid doing that. >> - Factor out ext4_[ext|ind]_map_blocks() parts from ext4_map_blocks(), >> introduce a new helper ext4_iomap_map_one_extent() to allocate >> delalloc blocks in writeback, which is always under i_data_sem in >> write mode. This is done to prevent the writing back delalloc >> extents become stale if it raced by truncate. >> - Add a lock detection in mapping_clear_large_folios(). >> Changes since v1: >> - Introduce seq count for iomap buffered write and writeback to protect >> races from extents changes, e.g. truncate, mwrite. >> - Always allocate unwritten extents for new blocks, drop dioread_lock >> mode, and make no distinctions between dioread_lock and >> dioread_nolock. >> - Don't add ditry data range to jinode, drop data=ordered mode, and >> make no distinctions between data=ordered and data=writeback mode. >> - Postpone updating i_disksize to endio. >> - Allow splitting extents and use reserved space in endio. >> - Instead of reimplement a new delayed mapping helper >> ext4_iomap_da_map_blocks() for buffer write, try to reuse >> ext4_da_map_blocks(). >> - Add support for disabling large folio on active inodes. >> - Support online defragmentation, make file fall back to buffer_head >> and disable large folio in ext4_move_extents(). >> - Move ext4_nonda_switch() in advance to prevent deadlock in mwrite. >> - Add dirty_len and pos trace info to trace_iomap_writepage_map(). >> - Update patch 1-6 to v2. >> >> This series only support ext4 with the default features and mount >> options, doesn't support inline_data, bigalloc, dax, fs_verity, fs_crypt >> and data=journal mode, ext4 would fall back to buffer_head path > > Do you plan to add bigalloc or !extents support as a part 2 patchset? Hello, Sorry for the late reply since I was on the vacation of Chinese New Year. I've been working on bigalloc support recently and it's going relatively well, but have no plans to support !extents yet, I would start looking into it after I finish rebasing my another patch set "ext4: more accurate metadata reservaion for delalloc mount option" mentioned in my TODO list. > > An ext2 port to iomap has been (vaguely) in the works for a while, > though iirc willy never got the performance to match because iomap > didn't have a mechanism for the caller to tell it "run the IO now even > though you don't have a complete page, because the indirect block is the > next block after the 11th block". > Thanks for pointing this out and the explanation given by Matthew. IIUC, this problem also affects ext4 in !extents mode, but not affects bigalloc, right? Thanks, Yi.
"Darrick J. Wong" <djwong@kernel.org> writes: > On Sat, Jan 27, 2024 at 09:57:59AM +0800, Zhang Yi wrote: >> From: Zhang Yi <yi.zhang@huawei.com> >> >> Hello, >> >> This is the third version of RFC patch series that convert ext4 regular >> file's buffered IO path to iomap and enable large folio. It's rebased on >> 6.7 and Christoph's "map multiple blocks per ->map_blocks in iomap >> writeback" series [1]. I've fixed all issues found in the last about 3 >> weeks of stress tests and fault injection tests in v2. I hope I've >> covered most of the corner cases, and any comments are welcome. :) >> >> Changes since v2: >> - Update patch 1-6 to v3 [2]. >> - iomap_zero and iomap_unshare don't need to update i_size and call >> iomap_write_failed(), introduce a new helper iomap_write_end_simple() >> to avoid doing that. >> - Factor out ext4_[ext|ind]_map_blocks() parts from ext4_map_blocks(), >> introduce a new helper ext4_iomap_map_one_extent() to allocate >> delalloc blocks in writeback, which is always under i_data_sem in >> write mode. This is done to prevent the writing back delalloc >> extents become stale if it raced by truncate. >> - Add a lock detection in mapping_clear_large_folios(). >> Changes since v1: >> - Introduce seq count for iomap buffered write and writeback to protect >> races from extents changes, e.g. truncate, mwrite. >> - Always allocate unwritten extents for new blocks, drop dioread_lock >> mode, and make no distinctions between dioread_lock and >> dioread_nolock. >> - Don't add ditry data range to jinode, drop data=ordered mode, and >> make no distinctions between data=ordered and data=writeback mode. >> - Postpone updating i_disksize to endio. >> - Allow splitting extents and use reserved space in endio. >> - Instead of reimplement a new delayed mapping helper >> ext4_iomap_da_map_blocks() for buffer write, try to reuse >> ext4_da_map_blocks(). >> - Add support for disabling large folio on active inodes. >> - Support online defragmentation, make file fall back to buffer_head >> and disable large folio in ext4_move_extents(). >> - Move ext4_nonda_switch() in advance to prevent deadlock in mwrite. >> - Add dirty_len and pos trace info to trace_iomap_writepage_map(). >> - Update patch 1-6 to v2. >> >> This series only support ext4 with the default features and mount >> options, doesn't support inline_data, bigalloc, dax, fs_verity, fs_crypt >> and data=journal mode, ext4 would fall back to buffer_head path > > Do you plan to add bigalloc or !extents support as a part 2 patchset? > Hi Darrick, > An ext2 port to iomap has been (vaguely) in the works for a while, yes, we have [1][2]. I am in the process of rebasing that work on the latest upstream. It's been a while since my last post since I have been pulled into some other internal work, sorry about that. > though iirc willy never got the performance to match because iomap Ohh, can you help me provide details on what performance benchmark was run? I can try and run them when I rebase. > didn't have a mechanism for the caller to tell it "run the IO now even > though you don't have a complete page, because the indirect block is the > next block after the 11th block". Do you mean this for a large folio? I still didn't get the problem you are referring here. Can you please help me explain why could that be a problem? [1]: https://lore.kernel.org/linux-ext4/9cdd449fc1d63cf2dba17cfa2fa7fb29b8f96a46.1700506526.git.ritesh.list@gmail.com/ [2]: https://lore.kernel.org/linux-ext4/8734wnj53k.fsf@doe.com/ -ritesh
On Mon, Feb 12, 2024 at 02:46:10PM +0530, Ritesh Harjani wrote: > "Darrick J. Wong" <djwong@kernel.org> writes: > > though iirc willy never got the performance to match because iomap > > Ohh, can you help me provide details on what performance benchmark was > run? I can try and run them when I rebase. I didn't run a benchmark, we just knew what would happen (on rotating storage anyway). > > didn't have a mechanism for the caller to tell it "run the IO now even > > though you don't have a complete page, because the indirect block is the > > next block after the 11th block". > > Do you mean this for a large folio? I still didn't get the problem you > are referring here. Can you please help me explain why could that be a > problem? A classic ext2 filesystem lays out a 16kB file like this (with 512 byte blocks): file offset disk block 0-6KiB 1000-1011 6KiB-16KiB 1013-1032 What's in block 1012? The indirect block! The block which tells ext2 that blocks 12-31 of the file are in disk blocks 1013-1032. So we can't issue the read for them until we've finished the read for block 1012. Buffer heads have a solution for this, BH_Boundary. ext2 sets it for block 11 which prompts mpage.c to submit the read immediately (see the various calls to buffer_boundary()). Then ext2 will submit the read for block 1012 and the two reads will be coalesced by the IO scheduler. So we still end up doing two reads instead of one, but that's unavoidable because fragmentation might have meant that 6KiB-16KiB were not stored at 1013-1032. There's no equivalent iomap solution. What needs to happen is: - iomap_folio_state->read_bytes_pending needs to be initialised to folio_size(), not 0. - Remove "ifs->read_bytes_pending += plen" from iomap_readpage_iter() - Subtract plen in the iomap_block_needs_zeroing() case - Submit a bio at the end of each iomap_readpage_iter() call Now iomap will behave the same way as mpage, only without needing a flag to do it (instead it will assume that the filesystem coalesces adjacent ranges, which it should do anyway for good performance).
© 2016 - 2025 Red Hat, Inc.