Re: [PATCH v3 2/2] nilfs2: switch O_DIRECT to iomap based operations

Ryusuke Konishi <[email protected]>
Newsgroups org.kernel.vger.linux-nilfs,org.kernel.vger.linux-fsdevel
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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.