nilfs2: switch O_DIRECT to iomap based operations

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".

cc: Christoph Hellwig <hch@lst.de>
cc: Ryusuke Konishi <konishi.ryusuke@gmail.com>
cc: linux-nilfs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
This commit is contained in:
Viacheslav Dubeyko 2026-08-12 15:11:54 -07:00
parent 89eebc9b5f
commit 081653dbea
3 changed files with 40 additions and 17 deletions

View File

@ -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

View File

@ -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,

View File

@ -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,
};