Re: [PATCH v3 2/2] nilfs2: switch O_DIRECT to iomap based operations
Ryusuke Konishi <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-nilfs |
|---|---|
| Message-ID | <CAKFNMokYNKF3-gQ1SctOqNJ6YfQAG=7khKRZGLYOpCmY63j2Rw@mail.gmail.com> |
On Thu, Aug 13, 2026 at 7:12 AM Viacheslav Dubeyko wrote: > > The patch eliminates blockdev_direct_IO() from > nilfs2 entirely: > > - nilfs_file_open() now sets FMODE_CAN_ODIRECT explicitly, since > permission to open the file O_DIRECT was previously implied by > aops->direct_IO being non-NULL. > - 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() as before. > - nilfs_file_write_iter() strips IOCB_DIRECT and falls through to > generic_file_write_iter()'s ordinary buffered path. NILFS2 cannot > perform true direct I/O writes: new blocks are delay-allocated and > only given a real disk address by the segment constructor, which > works on buffer_head lists, not iomap. This reproduces today's > actual behavior: the old nilfs_direct_IO() already just returned 0 > for WRITE. > - nilfs_direct_IO() and the .direct_IO callback on nilfs_aops are > removed. > - drop the unnecessary "select LEGACY_DIRECT_IO" from Kconfig > in favor of "select FS_IOMAP". > > Signed-off-by: Viacheslav Dubeyko <[email protected]> > cc: Christoph Hellwig <[email protected]> > cc: Ryusuke Konishi <[email protected]> > cc: [email protected] > cc: [email protected] > --- Acked-by: Ryusuke Konishi <[email protected]> Thanks, Ryusuke Konishi > fs/nilfs2/Kconfig | 2 +- > fs/nilfs2/file.c | 42 +++++++++++++++++++++++++++++++++++++++--- > fs/nilfs2/inode.c | 13 ------------- > 3 files changed, 40 insertions(+), 17 deletions(-) > > diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig > index 7dae168e346e..0a5ace60e6ab 100644 > --- a/fs/nilfs2/Kconfig > +++ b/fs/nilfs2/Kconfig > @@ -3,7 +3,7 @@ config NILFS2_FS > tristate "NILFS2 file system support" > select BUFFER_HEAD > select CRC32 > - select LEGACY_DIRECT_IO > + select FS_IOMAP > help > NILFS2 is a log-structured file system (LFS) supporting continuous > snapshotting. In addition to versioning capability of the entire > diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c > index f93b68c4877c..30dd8e5ebe5b 100644 > --- a/fs/nilfs2/file.c > +++ b/fs/nilfs2/file.c > @@ -10,9 +10,12 @@ > #include <linux/fs.h> > #include <linux/filelock.h> > #include <linux/mm.h> > +#include <linux/uio.h> > +#include <linux/iomap.h> > #include <linux/writeback.h> > #include "nilfs.h" > #include "segment.h" > +#include "iomap.h" > > int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) > { > @@ -133,20 +136,53 @@ static int nilfs_file_mmap_prepare(struct vm_area_desc *desc) > return 0; > } > > +static int nilfs_file_open(struct inode *inode, struct file *file) > +{ > + file->f_mode |= FMODE_CAN_ODIRECT; > + return generic_file_open(inode, file); > +} > + > +static ssize_t nilfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) > +{ > + struct inode *inode = file_inode(iocb->ki_filp); > + ssize_t ret; > + > + if (iocb->ki_flags & IOCB_DIRECT) { > + inode_lock_shared(inode); > + ret = iomap_dio_rw(iocb, to, &nilfs_iomap_ops, > + NULL, 0, NULL, 0); > + inode_unlock_shared(inode); > + } else > + ret = generic_file_read_iter(iocb, to); > + > + return ret; > +} > + > +static ssize_t nilfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) > +{ > + /* > + * NILFS2 lacks direct I/O write support: fall back to buffered writes. > + */ > + if (iocb->ki_flags & IOCB_DIRECT) > + iocb->ki_flags &= ~IOCB_DIRECT; > + > + return generic_file_write_iter(iocb, from); > +} > + > /* > * We have mostly NULL's here: the current defaults are ok for > * the nilfs filesystem. > */ > const struct file_operations nilfs_file_operations = { > .llseek = generic_file_llseek, > - .read_iter = generic_file_read_iter, > - .write_iter = generic_file_write_iter, > + .read_iter = nilfs_file_read_iter, > + .write_iter = nilfs_file_write_iter, > .unlocked_ioctl = nilfs_ioctl, > #ifdef CONFIG_COMPAT > .compat_ioctl = nilfs_compat_ioctl, > #endif /* CONFIG_COMPAT */ > .mmap_prepare = nilfs_file_mmap_prepare, > - .open = generic_file_open, > + .open = nilfs_file_open, > /* .release = nilfs_release_file, */ > .fsync = nilfs_sync_file, > .splice_read = filemap_splice_read, > diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c > index 34e6096069ad..cbe9658ae065 100644 > --- a/fs/nilfs2/inode.c > +++ b/fs/nilfs2/inode.c > @@ -257,18 +257,6 @@ static int nilfs_write_end(const struct kiocb *iocb, > return err ? : copied; > } > > -static ssize_t > -nilfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) > -{ > - struct inode *inode = file_inode(iocb->ki_filp); > - > - if (iov_iter_rw(iter) == WRITE) > - return 0; > - > - /* Needs synchronization with the cleaner */ > - return blockdev_direct_IO(iocb, inode, iter, nilfs_get_block); > -} > - > const struct address_space_operations nilfs_aops = { > .read_folio = nilfs_read_folio, > .writepages = nilfs_writepages, > @@ -277,7 +265,6 @@ const struct address_space_operations nilfs_aops = { > .write_begin = nilfs_write_begin, > .write_end = nilfs_write_end, > .invalidate_folio = block_invalidate_folio, > - .direct_IO = nilfs_direct_IO, > .migrate_folio = buffer_migrate_folio_norefs, > .is_partially_uptodate = block_is_partially_uptodate, > }; > -- > 2.43.0 >