The iomap handling of tails doesn't support multi-page folios, so convert it to call folio_copy_tail(), which does. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- fs/iomap/buffered-io.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 10a203515583..d08edf2de19c 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -215,31 +215,20 @@ static int iomap_read_inline_data(const struct iomap_iter *iter, { struct iomap_page *iop; const struct iomap *iomap = iomap_iter_srcmap(iter); - size_t size = i_size_read(iter->inode) - iomap->offset; - size_t poff = offset_in_page(iomap->offset); - size_t offset = offset_in_folio(folio, iomap->offset); - void *addr; + loff_t pos = iomap->offset; if (folio_test_uptodate(folio)) return 0; - if (WARN_ON_ONCE(size > PAGE_SIZE - poff)) - return -EIO; - if (WARN_ON_ONCE(size > PAGE_SIZE - - offset_in_page(iomap->inline_data))) - return -EIO; - if (WARN_ON_ONCE(size > iomap->length)) - return -EIO; - if (offset > 0) + if (pos > folio_pos(folio)) iop = iomap_page_create(iter->inode, folio, iter->flags); else iop = to_iomap_page(folio); - addr = kmap_local_folio(folio, offset); - memcpy(addr, iomap->inline_data, size); - memset(addr + size, 0, PAGE_SIZE - poff - size); - kunmap_local(addr); - iomap_set_range_uptodate(folio, iop, offset, PAGE_SIZE - poff); + folio_copy_tail(folio, pos, iomap->inline_data, + iomap->length); + iomap_set_range_uptodate(folio, iop, pos - folio_pos(folio), + folio_size(folio) - offset_in_folio(folio, pos)); return 0; } -- 2.39.1