On Tue, Jul 20, 2021 at 01:34:58PM +0200, Andreas Grünbacher wrote: > Am Mo., 19. Juli 2021 um 16:48 Uhr schrieb Gao Xiang > <hsiangkao@xxxxxxxxxxxxxxxxx>: > > This tries to add tail packing inline read to iomap, which can support > > several inline tail blocks. Similar to the previous approach, it cleans > > post-EOF in one iteration. > > > > The write path remains untouched since EROFS cannot be used for testing. > > It'd be better to be implemented if upcoming real users care rather than > > leave untested dead code around. > > > > Cc: Christoph Hellwig <hch@xxxxxx> > > Cc: Darrick J. Wong <djwong@xxxxxxxxxx> > > Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> > > Cc: Andreas Gruenbacher <andreas.gruenbacher@xxxxxxxxx> > > Signed-off-by: Gao Xiang <hsiangkao@xxxxxxxxxxxxxxxxx> > > --- > > v2: https://lore.kernel.org/r/YPLdSja%2F4FBsjss%2F@B-P7TQMD6M-0146.local/ > > changes since v2: > > - update suggestion from Christoph: > > https://lore.kernel.org/r/YPVe41YqpfGLNsBS@xxxxxxxxxxxxx/ > > > > Hi Andreas, > > would you mind test on the gfs2 side? Thanks in advance! > > > > Thanks, > > Gao Xiang > > > > fs/iomap/buffered-io.c | 50 ++++++++++++++++++++++++++---------------- > > fs/iomap/direct-io.c | 11 ++++++---- > > 2 files changed, 38 insertions(+), 23 deletions(-) > > > > diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c > > index 87ccb3438bec..cac8a88660d8 100644 > > --- a/fs/iomap/buffered-io.c > > +++ b/fs/iomap/buffered-io.c > > @@ -207,23 +207,22 @@ struct iomap_readpage_ctx { > > > > static void > > iomap_read_inline_data(struct inode *inode, struct page *page, > > - struct iomap *iomap) > > + struct iomap *iomap, loff_t pos) > > { > > - size_t size = i_size_read(inode); > > + unsigned int size, poff = offset_in_page(pos); > > void *addr; > > > > - if (PageUptodate(page)) > > - return; > > - > > - BUG_ON(page_has_private(page)); > > - BUG_ON(page->index); > > - BUG_ON(size > PAGE_SIZE - offset_in_page(iomap->inline_data)); > > + /* inline source data must be inside a single page */ > > + BUG_ON(iomap->length > PAGE_SIZE - offset_in_page(iomap->inline_data)); > > + /* handle tail-packing blocks cross the current page into the next */ > > + size = min_t(unsigned int, iomap->length + pos - iomap->offset, > > + PAGE_SIZE - poff); > > > > addr = kmap_atomic(page); > > - memcpy(addr, iomap->inline_data, size); > > - memset(addr + size, 0, PAGE_SIZE - size); > > + memcpy(addr + poff, iomap->inline_data - iomap->offset + pos, size); > > + memset(addr + poff + size, 0, PAGE_SIZE - poff - size); > > kunmap_atomic(addr); > > - SetPageUptodate(page); > > + iomap_set_range_uptodate(page, poff, PAGE_SIZE - poff); > > } > > > > static inline bool iomap_block_needs_zeroing(struct inode *inode, > > @@ -246,18 +245,19 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data, > > unsigned poff, plen; > > sector_t sector; > > > > - if (iomap->type == IOMAP_INLINE) { > > - WARN_ON_ONCE(pos); > > - iomap_read_inline_data(inode, page, iomap); > > - return PAGE_SIZE; > > - } > > - > > - /* zero post-eof blocks as the page may be mapped */ > > iop = iomap_page_create(inode, page); > > We can skip creating the iop when reading the entire page. As I said before, I think it can be in a separated patch like https://lore.kernel.org/r/YPMkKfegS+9KzEhK@xxxxxxxxxxxxxxxxxxxx/ and Christoph said it should be careful: https://lore.kernel.org/r/YPVfxn6%2FoCPBZpKu@xxxxxxxxxxxxx/ Thanks, Gao Xiang