Re: [PATCH v3 1/2] nilfs2: add iomap operations for direct I/O
Ryusuke Konishi <[email protected]>
| Newsgroups | org.kernel.vger.linux-nilfs,org.kernel.vger.linux-fsdevel |
|---|---|
| Message-ID | <CAKFNMokgEToO6Hm=3pVYLA6BFBJfnysK6KmxK4k0=xU1ttGGCw@mail.gmail.com> |
On Thu, Aug 13, 2026 at 7:12 AM Viacheslav Dubeyko wrote: > > The patch adds iomap.h with declaration of iomaps > operations and iomap.c with implementation of > nilfs_iomap_begin(). This method is based on calling > the nilfs_bmap_lookup_contig() method. It resolves > the file's block-mapping to find the sequence of > physically-contiguous blocks starting at starting > block. Offsets at or beyond i_size are reported > as a hole. For offsets within i_size, the requested > length is first clamped to the block-aligned end of the file. > Both the hole and mapped cases then report iomap->offset > aligned to the containing block (blkoff << i_blkbits) > rather than the raw request offset. > > Signed-off-by: Viacheslav Dubeyko <[email protected]> > Co-developed-by: Linmao Li <[email protected]> > Signed-off-by: Linmao Li <[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/Makefile | 2 +- > fs/nilfs2/iomap.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ > fs/nilfs2/iomap.h | 13 +++++++++ > 3 files changed, 86 insertions(+), 1 deletion(-) > create mode 100644 fs/nilfs2/iomap.c > create mode 100644 fs/nilfs2/iomap.h > > diff --git a/fs/nilfs2/Makefile b/fs/nilfs2/Makefile > index 43b60b8a4d07..516e6b85a03c 100644 > --- a/fs/nilfs2/Makefile > +++ b/fs/nilfs2/Makefile > @@ -3,4 +3,4 @@ obj-$(CONFIG_NILFS2_FS) += nilfs2.o > nilfs2-y := inode.o file.o dir.o super.o namei.o page.o mdt.o \ > btnode.o bmap.o btree.o direct.o dat.o recovery.o \ > the_nilfs.o segbuf.o segment.o cpfile.o sufile.o \ > - ifile.o alloc.o gcinode.o ioctl.o sysfs.o > + ifile.o alloc.o gcinode.o ioctl.o sysfs.o iomap.o > diff --git a/fs/nilfs2/iomap.c b/fs/nilfs2/iomap.c > new file mode 100644 > index 000000000000..e130ed63abd9 > --- /dev/null > +++ b/fs/nilfs2/iomap.c > @@ -0,0 +1,72 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * NILFS iomap support implementation. > + * > + * Written by Viacheslav Dubeyko. > + */ > + > +#include <linux/iomap.h> > +#include <linux/pagemap.h> > +#include "nilfs.h" > +#include "mdt.h" > +#include "iomap.h" > + > +static int nilfs_iomap_begin(struct inode *inode, loff_t offset, > + loff_t length, unsigned int flags, > + struct iomap *iomap, struct iomap *srcmap) > +{ > + struct the_nilfs *nilfs = inode->i_sb->s_fs_info; > + struct nilfs_inode_info *ii = NILFS_I(inode); > + sector_t blkoff = offset >> inode->i_blkbits; > + loff_t iomap_offset = (loff_t)blkoff << inode->i_blkbits; > + unsigned int maxblocks; > + __u64 blknum = 0; > + int ret; > + > + /* Completely beyond EOF. Treat as hole */ > + if (i_size_read(inode) <= offset) { > + iomap->type = IOMAP_HOLE; > + iomap->addr = IOMAP_NULL_ADDR; > + iomap->offset = offset; > + iomap->length = length; > + return 0; > + } > + > + /* Clamp length if the requested range goes beyond i_size */ > + if (offset + length > i_size_read(inode)) { > + loff_t i_size = i_size_read(inode); > + unsigned int blocksize = i_blocksize(inode); > + > + length = round_up(i_size, blocksize) - offset; > + } > + > + maxblocks = min_t(loff_t, length >> inode->i_blkbits, INT_MAX); > + if (maxblocks == 0) > + maxblocks = 1; > + > + down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); > + ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); > + up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); > + > + if (ret == -ENOENT) { > + iomap->type = IOMAP_HOLE; > + iomap->addr = IOMAP_NULL_ADDR; > + iomap->offset = iomap_offset; > + iomap->length = i_blocksize(inode); > + return 0; > + } else if (ret < 0) > + return ret; > + > + iomap->bdev = inode->i_sb->s_bdev; > + iomap->offset = iomap_offset; > + iomap->length = (loff_t)ret << inode->i_blkbits; > + iomap->addr = (loff_t)blknum << inode->i_blkbits; > + iomap->type = IOMAP_MAPPED; > + iomap->flags = IOMAP_F_MERGED; > + > + return 0; > +} > + > +const struct iomap_ops nilfs_iomap_ops = { > + .iomap_begin = nilfs_iomap_begin, > +}; > diff --git a/fs/nilfs2/iomap.h b/fs/nilfs2/iomap.h > new file mode 100644 > index 000000000000..adef3e22346d > --- /dev/null > +++ b/fs/nilfs2/iomap.h > @@ -0,0 +1,13 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * NILFS iomap support declarations. > + * > + * Written by Viacheslav Dubeyko. > + */ > + > +#ifndef _NILFS_IOMAP_H > +#define _NILFS_IOMAP_H > + > +extern const struct iomap_ops nilfs_iomap_ops; > + > +#endif /* _NILFS_IOMAP_H */ > -- > 2.43.0 >