[PATCH v3 0/2] nilfs2: eliminate blockdev_direct_IO() call
Viacheslav Dubeyko <[email protected]>
| Newsgroups | org.kernel.vger.linux-nilfs,org.kernel.vger.linux-fsdevel |
|---|---|
| Message-ID | <[email protected]> |
The patchset eliminates blockdev_direct_IO() from nilfs2 entirely. It adds iomap.h with declaration of iomaps operations and iomap.c with implementation of nilfs_iomap_begin(). The nilfs_direct_IO() and the .direct_IO callback on nilfs_aops are removed. The nilfs_file_read_iter() dispatches O_DIRECT reads to iomap_dio_rw() using nilfs_iomap_ops. Everything else still goes through generic_file_read_iter(). The unnecessary "select LEGACY_DIRECT_IO" has been exchanged on "select FS_IOMAP" in Kconfig. v2 The bug has been discovered in nilfs_iomap_begin() of patchset's first version thanks to Linmao Li. nilfs_iomap_begin() looks up the filesystem block containing the requested offset and returns the physical address of that block. However, it sets iomap->offset to the original, possibly sub-block, offset while leaving iomap->addr at the start of the physical block. iomap_sector() adds the difference between the I/O position and iomap->offset to iomap->addr. For an O_DIRECT read at offset 512 on a filesystem with 4 KiB blocks, the two file offsets are equal and the I/O is therefore submitted at the start of the physical block instead of 512 bytes into it. iomap direct I/O permits this alignment when the device logical block size is 512 bytes. Describe mapped and hole extents from the filesystem-block-aligned file offset. This makes the physical and file offsets refer to the same byte. It also prevents a one-block hole mapping from extending into the following block. v3 Ryusuke Konishi has found issues with generic/418 and generic/465 test-cases execution. Running xfstests generic/418 and generic/465 fail with a "broken bmap" error, causing the filesystem to remount read-only for the second version of the patchset. This happens because iomap_dio_rw() is called without holding the shared inode lock. Adding inode_lock_shared() for the case of calling iomap_dio_rw() in nilfs_file_read_iter() resolved the failures in both generic/418 and generic/465 test-cases. Viacheslav Dubeyko (2): nilfs2: add iomap operations for direct I/O nilfs2: switch O_DIRECT to iomap based operations fs/nilfs2/Kconfig | 2 +- fs/nilfs2/Makefile | 2 +- fs/nilfs2/file.c | 42 +++++++++++++++++++++++++-- fs/nilfs2/inode.c | 13 --------- fs/nilfs2/iomap.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ fs/nilfs2/iomap.h | 13 +++++++++ 6 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 fs/nilfs2/iomap.c create mode 100644 fs/nilfs2/iomap.h -- 2.43.0