diff options
| author | Christoph Hellwig <hch@lst.de> | 2025-07-10 15:33:28 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2025-07-14 10:51:31 +0200 |
| commit | fb7399cf2d0b33825b8039f95c45395c7deba25c (patch) | |
| tree | 849825cc5c90ac56c4a163db7eac3752e92d7f12 /block | |
| parent | iomap: cleanup the pending writeback tracking in iomap_writepage_map_blocks (diff) | |
| download | linux-fb7399cf2d0b33825b8039f95c45395c7deba25c.tar.gz linux-fb7399cf2d0b33825b8039f95c45395c7deba25c.zip | |
iomap: refactor the writeback interface
Replace ->map_blocks with a new ->writeback_range, which differs in the
following ways:
- it must also queue up the I/O for writeback, that is called into the
slightly refactored and extended in scope iomap_add_to_ioend for
each region
- can handle only a part of the requested region, that is the retry
loop for partial mappings moves to the caller
- handles cleanup on failures as well, and thus also replaces the
discard_folio method only implemented by XFS.
This will allow to use the iomap writeback code also for file systems
that are not block based like fuse.
Co-developed-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/20250710133343.399917-5-hch@lst.de
Acked-by: Damien Le Moal <dlemoal@kernel.org> # zonefs
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'block')
| -rw-r--r-- | block/fops.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/block/fops.c b/block/fops.c index 3394263d942b..b500ff8f55dd 100644 --- a/block/fops.c +++ b/block/fops.c @@ -537,22 +537,29 @@ static void blkdev_readahead(struct readahead_control *rac) iomap_readahead(rac, &blkdev_iomap_ops); } -static int blkdev_map_blocks(struct iomap_writepage_ctx *wpc, - struct inode *inode, loff_t offset, unsigned int len) +static ssize_t blkdev_writeback_range(struct iomap_writepage_ctx *wpc, + struct folio *folio, u64 offset, unsigned int len, u64 end_pos) { - loff_t isize = i_size_read(inode); + loff_t isize = i_size_read(wpc->inode); if (WARN_ON_ONCE(offset >= isize)) return -EIO; - if (offset >= wpc->iomap.offset && - offset < wpc->iomap.offset + wpc->iomap.length) - return 0; - return blkdev_iomap_begin(inode, offset, isize - offset, - IOMAP_WRITE, &wpc->iomap, NULL); + + if (offset < wpc->iomap.offset || + offset >= wpc->iomap.offset + wpc->iomap.length) { + int error; + + error = blkdev_iomap_begin(wpc->inode, offset, isize - offset, + IOMAP_WRITE, &wpc->iomap, NULL); + if (error) + return error; + } + + return iomap_add_to_ioend(wpc, folio, offset, end_pos, len); } static const struct iomap_writeback_ops blkdev_writeback_ops = { - .map_blocks = blkdev_map_blocks, + .writeback_range = blkdev_writeback_range, }; static int blkdev_writepages(struct address_space *mapping, |
