diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-01-14 16:31:46 +0100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-01-14 16:31:46 +0100 |
| commit | 3431d387a7042c754e27152c287c6e706b46f139 (patch) | |
| tree | 39801f60da8748aa44aae13f7aa0b3050118737b | |
| parent | 8f0b4cce4481fb22653697cced8d0d04027cb1e8 (diff) | |
| parent | 8d407bb32186f4a06a97871af4d5cc45444602fb (diff) | |
Merge patch series "iomap: erofs page cache sharing preliminaries"
Bring in the two changes needed in iomap and erofs to enable the page
cache sharing work.
* patches from https://patch.msgid.link/20260109102856.598531-1-lihongbo22@huawei.com:
erofs: hold read context in iomap_iter if needed
iomap: stash iomap read ctx in the private field of iomap_iter
Link: https://patch.msgid.link/20260109102856.598531-1-lihongbo22@huawei.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
| -rw-r--r-- | fs/erofs/data.c | 67 | ||||
| -rw-r--r-- | fs/fuse/file.c | 4 | ||||
| -rw-r--r-- | fs/iomap/buffered-io.c | 6 | ||||
| -rw-r--r-- | include/linux/iomap.h | 8 |
4 files changed, 56 insertions, 29 deletions
diff --git a/fs/erofs/data.c b/fs/erofs/data.c index bb13c4cb8455..71e23d91123d 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -266,13 +266,20 @@ void erofs_onlinefolio_end(struct folio *folio, int err, bool dirty) folio_end_read(folio, !(v & BIT(EROFS_ONLINEFOLIO_EIO))); } +struct erofs_iomap_iter_ctx { + struct page *page; + void *base; +}; + static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, unsigned int flags, struct iomap *iomap, struct iomap *srcmap) { - int ret; + struct iomap_iter *iter = container_of(iomap, struct iomap_iter, iomap); + struct erofs_iomap_iter_ctx *ctx = iter->private; struct super_block *sb = inode->i_sb; struct erofs_map_blocks map; struct erofs_map_dev mdev; + int ret; map.m_la = offset; map.m_llen = length; @@ -283,7 +290,6 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, iomap->offset = map.m_la; iomap->length = map.m_llen; iomap->flags = 0; - iomap->private = NULL; iomap->addr = IOMAP_NULL_ADDR; if (!(map.m_flags & EROFS_MAP_MAPPED)) { iomap->type = IOMAP_HOLE; @@ -309,16 +315,20 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, } if (map.m_flags & EROFS_MAP_META) { - void *ptr; - struct erofs_buf buf = __EROFS_BUF_INITIALIZER; - iomap->type = IOMAP_INLINE; - ptr = erofs_read_metabuf(&buf, sb, map.m_pa, - erofs_inode_in_metabox(inode)); - if (IS_ERR(ptr)) - return PTR_ERR(ptr); - iomap->inline_data = ptr; - iomap->private = buf.base; + /* read context should read the inlined data */ + if (ctx) { + struct erofs_buf buf = __EROFS_BUF_INITIALIZER; + void *ptr; + + ptr = erofs_read_metabuf(&buf, sb, map.m_pa, + erofs_inode_in_metabox(inode)); + if (IS_ERR(ptr)) + return PTR_ERR(ptr); + iomap->inline_data = ptr; + ctx->page = buf.page; + ctx->base = buf.base; + } } else { iomap->type = IOMAP_MAPPED; } @@ -328,18 +338,18 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, static int erofs_iomap_end(struct inode *inode, loff_t pos, loff_t length, ssize_t written, unsigned int flags, struct iomap *iomap) { - void *ptr = iomap->private; + struct iomap_iter *iter = container_of(iomap, struct iomap_iter, iomap); + struct erofs_iomap_iter_ctx *ctx = iter->private; - if (ptr) { + if (ctx && ctx->base) { struct erofs_buf buf = { - .page = kmap_to_page(ptr), - .base = ptr, + .page = ctx->page, + .base = ctx->base, }; DBG_BUGON(iomap->type != IOMAP_INLINE); erofs_put_metabuf(&buf); - } else { - DBG_BUGON(iomap->type == IOMAP_INLINE); + ctx->base = NULL; } return written; } @@ -369,18 +379,30 @@ int erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, */ static int erofs_read_folio(struct file *file, struct folio *folio) { + struct iomap_read_folio_ctx read_ctx = { + .ops = &iomap_bio_read_ops, + .cur_folio = folio, + }; + struct erofs_iomap_iter_ctx iter_ctx = {}; + trace_erofs_read_folio(folio, true); - iomap_bio_read_folio(folio, &erofs_iomap_ops); + iomap_read_folio(&erofs_iomap_ops, &read_ctx, &iter_ctx); return 0; } static void erofs_readahead(struct readahead_control *rac) { + struct iomap_read_folio_ctx read_ctx = { + .ops = &iomap_bio_read_ops, + .rac = rac, + }; + struct erofs_iomap_iter_ctx iter_ctx = {}; + trace_erofs_readahead(rac->mapping->host, readahead_index(rac), readahead_count(rac), true); - iomap_bio_readahead(rac, &erofs_iomap_ops); + iomap_readahead(&erofs_iomap_ops, &read_ctx, &iter_ctx); } static sector_t erofs_bmap(struct address_space *mapping, sector_t block) @@ -400,9 +422,12 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) if (IS_DAX(inode)) return dax_iomap_rw(iocb, to, &erofs_iomap_ops); #endif - if ((iocb->ki_flags & IOCB_DIRECT) && inode->i_sb->s_bdev) + if ((iocb->ki_flags & IOCB_DIRECT) && inode->i_sb->s_bdev) { + struct erofs_iomap_iter_ctx iter_ctx = {}; + return iomap_dio_rw(iocb, to, &erofs_iomap_ops, - NULL, 0, NULL, 0); + NULL, 0, &iter_ctx, 0); + } return filemap_read(iocb, to, 0); } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 01bc894e9c2b..f5d8887c1922 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -979,7 +979,7 @@ static int fuse_read_folio(struct file *file, struct folio *folio) return -EIO; } - iomap_read_folio(&fuse_iomap_ops, &ctx); + iomap_read_folio(&fuse_iomap_ops, &ctx, NULL); fuse_invalidate_atime(inode); return 0; } @@ -1081,7 +1081,7 @@ static void fuse_readahead(struct readahead_control *rac) if (fuse_is_bad(inode)) return; - iomap_readahead(&fuse_iomap_ops, &ctx); + iomap_readahead(&fuse_iomap_ops, &ctx, NULL); } static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to) diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index e5c1ca440d93..5f7dcbabbda3 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -555,13 +555,14 @@ static int iomap_read_folio_iter(struct iomap_iter *iter, } void iomap_read_folio(const struct iomap_ops *ops, - struct iomap_read_folio_ctx *ctx) + struct iomap_read_folio_ctx *ctx, void *private) { struct folio *folio = ctx->cur_folio; struct iomap_iter iter = { .inode = folio->mapping->host, .pos = folio_pos(folio), .len = folio_size(folio), + .private = private, }; size_t bytes_submitted = 0; int ret; @@ -620,13 +621,14 @@ static int iomap_readahead_iter(struct iomap_iter *iter, * the filesystem to be reentered. */ void iomap_readahead(const struct iomap_ops *ops, - struct iomap_read_folio_ctx *ctx) + struct iomap_read_folio_ctx *ctx, void *private) { struct readahead_control *rac = ctx->rac; struct iomap_iter iter = { .inode = rac->mapping->host, .pos = readahead_pos(rac), .len = readahead_length(rac), + .private = private, }; size_t cur_bytes_submitted; diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 520e967cb501..441d614e9fdf 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -341,9 +341,9 @@ ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from, const struct iomap_ops *ops, const struct iomap_write_ops *write_ops, void *private); void iomap_read_folio(const struct iomap_ops *ops, - struct iomap_read_folio_ctx *ctx); + struct iomap_read_folio_ctx *ctx, void *private); void iomap_readahead(const struct iomap_ops *ops, - struct iomap_read_folio_ctx *ctx); + struct iomap_read_folio_ctx *ctx, void *private); bool iomap_is_partially_uptodate(struct folio *, size_t from, size_t count); struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos, size_t len); bool iomap_release_folio(struct folio *folio, gfp_t gfp_flags); @@ -595,7 +595,7 @@ static inline void iomap_bio_read_folio(struct folio *folio, .cur_folio = folio, }; - iomap_read_folio(ops, &ctx); + iomap_read_folio(ops, &ctx, NULL); } static inline void iomap_bio_readahead(struct readahead_control *rac, @@ -606,7 +606,7 @@ static inline void iomap_bio_readahead(struct readahead_control *rac, .rac = rac, }; - iomap_readahead(ops, &ctx); + iomap_readahead(ops, &ctx, NULL); } #endif /* CONFIG_BLOCK */ |
